<pre class=metadata>
Title: Filter Effects Module Level 1
Status: ED
Work Status: Refining
ED: https://drafts.fxtf.org/filter-effects-1/
TR: https://www.w3.org/TR/filter-effects-1/
Previous Version: https://www.w3.org/TR/2018/WD-filter-effects-1-20181124/
Previous Version: https://www.w3.org/TR/2014/WD-filter-effects-1-20141125/
Previous Version: https://www.w3.org/TR/2013/WD-filter-effects-1-20131126/
Previous Version: https://www.w3.org/TR/2013/WD-filter-effects-20130523/
Previous Version: https://www.w3.org/TR/2012/WD-filter-effects-20121025/
Shortname: filter-effects
Level: 1
Group: fxtf
Editor: Dirk Schulze, Adobe Inc., dschulze@adobe.com, w3cid 51803
Editor: Dean Jackson, Apple Inc., dino@apple.com, w3cid 42080
Editor: Chris Harrelson, Google, chrishtr@google.com, w3cid 90243
Former Editor: Vincent Hardy
Former Editor: Erik Dahlström, Invited Expert, erik@dahlström.net
Test Suite: http://test.csswg.org/suites/filter-effects/nightly-unstable/
Abstract: Filter effects are a way of processing an element's rendering before it is displayed in the document. Typically, rendering an element via CSS or SVG can conceptually be described as if the element, including its children, are drawn into a buffer (such as a raster image) and then that buffer is composited into the elements parent. Filters apply an effect before the compositing stage. Examples of such effects are blurring, changing color intensity and warping the image.
Abstract:
Abstract: Although originally designed for use in SVG, filter effects are a set of operations to apply on an image buffer and therefore can be applied to nearly any presentational environment, including CSS. They are triggered by a style instruction (the 'filter' property). This specification describes filters in a manner that allows them to be used in content styled by CSS, such as HTML and SVG. It also defines a CSS property value function that produces a CSS <<image>> value.
Ignored Vars: Va, 5s, 10s
</pre>
<pre class=link-defaults>
spec:compositing-1; type:value;
    text:screen
    text:normal
    text:color
    text:saturation
spec:css21;
    type:type; text:<margin-width>
spec:css-text-decor-3; type:value; text:currentcolor
spec:css-backgrounds-3; type:property;
    text:border
    text:box-shadow
    text:border-image
spec:css-color-4; type:property; text:color
spec:css-color-4; type:value
    text:srgb
    text:srgb-linear
spec:css-fonts-3; type:property
    text:font-family
    text:font-stretch
    text:font-style
    text:font-variant
    text:font-weight
spec:css-masking-1; type:property
    text:clip-path
    text:clip
    text:clip-rule
    text:mask
spec:css-overflow-3;
    type:dfn; text:ink overflow area
    type:dfn; text:ink overflow rectangle
spec:css-transforms-1;
    type:property; text:transform
    type:type; text:<transform-function>
    type:dfn; text:local coordinate system
spec:selectors-4;
    type:selector; text::visited
    type:type; text:<compound-selector>
spec:svg2; type:property
    text:color-interpolation
    text:fill
    text:fill-opacity
    text:fill-rule
    text:stroke
    text:glyph-orientation-horizontal
    text:glyph-orientation-vertical
    text:marker-start
    text:marker-end
    text:marker-mid
    text:stop-color
    text:stop-opacity
    text:stroke-dasharray
    text:stroke-dashoffset
    text:stroke-linecap
    text:stroke-linejoin
    text:stroke-miterlimit
    text:stroke-opacity
    text:stroke-width
    text:text-anchor
    text:alignment-baseline
    text:baseline-shift
    text:dominant-baseline
spec:svg2; type:element
    text:script
    text:title
spec:web-animations-1;
    type:dfn; text: composite operation replace;
spec:html; type:dfn; for:/; text:browsing context
    https://html.spec.whatwg.org/multipage/browsers.html#browsing-context
spec:css-display-3; type:property; text:display
spec:filter-effects-1; type:value;
    text:in
    text:table
    text:linear
    text:lighter
</pre>
<pre class=anchors>
spec:svg12t; url:http://www.w3.org/TR/2008/REC-SVGTiny12-20081222/intro.html#TermUnsupportedValue; type:dfn; for:svg; text:unsupported
spec:svg2; url:https://svgwg.org/svg2-draft/coords.html#ObjectBoundingBoxUnits; type:dfn; for:svg; text:object bounding box units
spec:svg11; url:https://www.w3.org/TR/SVG11/masking.html#SimpleAlphaBlending; type:dfn; for:svg; text:simple alpha compositing
spec:svg2; url:https://svgwg.org/svg2-draft/types.html#TermInitialValue; type:dfn; for:svg; text:initial value
</pre>
<pre class=biblio>
{
    "ArTD": {
        "authors": [
            "B. Jacob"
        ],
        "href": "https://wiki.mozilla.org/User:Bjacob/ArithmeticTimingDifferences",
        "title": "Arithmetic Timing Differences"
    },
    "Cmam": {
        "authors": [
            "IEC"
        ],
        "href": "https://webstore.iec.ch/publication/6169",
        "title": "IEC 61966-2-1:1999 Colour measurement and management - Part 2-1: Colour management - Default RGB colour space - sRGB"
    },
    "TaM": {
        "authors": [
            "Ebert et al, AP Professional"
        ],
        "publisher": "AP Professional",
        "date": "1994",
        "title": "Texturing and Modeling"
    }
}
</pre>

<style type="text/css">
a[data-link-type=element]::before,span[data-link-type=element]::before {
  content: '<';
}
a[data-link-type=element]::after,span[data-link-type=element]::after {
  content: '>';
}
</style>

<script type="text/javascript" src="../shared/MathJax/MathJax.js?config=MML_SVGorMML,local/local"></script>

# Introduction # {#intro}

<em>This section is not normative</em>

A filter effect is a graphical operation that is applied to an element as it is drawn into the document. It is an image-based effect, in that it takes zero or more images as input, a number of parameters specific to the effect, and then produces an image as output. The output image is either rendered into the document instead of the original element, used as an input image to another filter effect, or provided as a CSS image value.

A simple example of a filter effect is a “flood”. It takes no image inputs but has a parameter defining a color. The effect produces an output image that is completely filled with the given color. A slightly more complex example is an “inversion” which takes a single image input (typically an image of the element as it would normally be rendered into its parent) and adjusts each pixel such that they have the opposite color values.

Filter effects are exposed with two levels of complexity:

1. A small set of canned filter functions that are given by name. While not particularly powerful, these are convenient and easily understood and provide a simple approach to achieving common effects, such as blurring. The canned filters can also be animated by [[CSS3-ANIMATIONS]].
2. A graph of individual filter effects described in markup that define an overall effect. The graph is agnostic to its input in that the effect can be applied to any content. While such graphs are the combination of effects that may be simple in isolation, the graph as a whole can produce complex effects. An example is given below.

<div class=example>
    In this example, an image is filtered with the <<grayscale()>> filter function.

    <pre><code highlight=css>
        #image {
            filter: grayscale(100%);
        }
    </code></pre>

    <div class=figure>
        <img src="images/grayscale.svg" width="451" height="260" alt="Example for grayscale filter applied to image">
        <p class=caption>An image without filter (left) and the same filter with a 100% grayscale filter (right).</p>
    </div>
</div>

<div class=example>
    The following shows an example of graph of individual filter effects.

    <div class=figure>
        <img src="examples/filters01.png" alt="Example Filter">
        <p class=caption>Initial example for a filtered object.</p>
    </div>

    <a href="examples/filters01.svg">View this example as SVG</a>

    The filter effect used in the example above is repeated here with reference numbers in the left column before each of the six filter primitives:

<table>
  <tbody>
    <tr>
      <td style="vertical-align: top">
<br>
<br>
1<br>
2<br>
3<br>
 <br>
 <br>
 <br>
 <br>
4<br>
5<br>
 <br>
6<br>
 <br>
 <br>
      </td>
      <td style="vertical-align: top"><pre highlight=svg data-line="3,4,5,10,11,13">&lt;filter id="MyFilter" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="120"&gt;
  &lt;desc&gt;Produces a 3D lighting effect.&lt;/desc&gt;
  &lt;feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/&gt;
  &lt;feOffset in="blur" dx="4" dy="4" result="offsetBlur"/&gt;
  &lt;feSpecularLighting in="blur" surfaceScale="5" specularConstant=".75"
                      specularExponent="20" lighting-color="#bbbbbb"
                      result="specOut"&gt;
    &lt;fePointLight x="-5000" y="-10000" z="20000"/&gt;
  &lt;/feSpecularLighting&gt;
  &lt;feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/&gt;
  &lt;feComposite in="SourceGraphic" in2="specOut" operator="arithmetic"
               k1="0" k2="1" k3="1" k4="0" result="litPaint"/&gt;
  &lt;feMerge&gt;
    &lt;feMergeNode in="offsetBlur"/&gt;
    &lt;feMergeNode in="litPaint"/&gt;
  &lt;/feMerge&gt;
&lt;/filter&gt;</pre>
      </td>
    </tr>
  </tbody>
</table>

The following pictures show the intermediate image results from each of the six filter elements:

<style type="text/css">
.primitive > div {
  width: 155px;
  margin: 10px;
  float: left;
  text-align: center;
}
.primitive div > img {
  border: solid black 1px;
}
</style>

<div class="primitive">
  <div>
    <img width="115" height="70" alt="filters01 - original source graphic" src="examples/filters01-0.png">
    <p>Source graphic</p>
  </div>
  <div>
    <img width="115" height="70" alt="filters01 - after filter element 1" src="examples/filters01-1.png">
    <p>After filter primitive 1</p>
  </div>
  <div>
    <img width="115" height="70" alt="filters01 - after filter element 2" src="examples/filters01-2.png">
    <p>After filter primitive 2</p>
  </div>
  <div class="primitive">
    <img width="115" height="70" alt="filters01 - after filter element 3" src="examples/filters01-3.png">
    <p>After filter primitive 3</p>
  </div>
  <div>
    <img width="115" height="70" alt="filters01 - after filter element 4" src="examples/filters01-4.png">
    <p>After filter primitive 4</p>
  </div>
  <div>
    <img width="115" height="70" alt="filters01 - after filter element 5" src="examples/filters01-5.png">
    <p>After filter primitive 5</p>
  </div>
  <div>
    <img width="115" height="70" alt="filters01 - after filter element 6" src="examples/filters01-6.png">
    <p>After filter primitive 6</p>
  </div>
</div>

<ol style="clear: left">
    1. Filter primitive <a element>feGaussianBlur</a> takes input <a attr-value>SourceAlpha</a>, which is the alpha channel of the source graphic. The result is stored in a temporary buffer named "blur". Note that "blur" is used as input to both filter primitives 2 and 3.
    2. Filter primitive <a element>feOffset</a> takes buffer "blur", shifts the result in a positive direction in both x and y, and creates a new buffer named "offsetBlur". The effect is that of a drop shadow.
    3. Filter primitive <a element>feSpecularLighting</a>, uses buffer "blur" as a model of a surface elevation and generates a lighting effect from a single point source. The result is stored in buffer "specOut".
    4. Filter primitive <a element>feComposite</a> masks out the result of filter primitive 3 by the original source graphics alpha channel so that the intermediate result is no bigger than the original source graphic.
    5. Filter primitive <a element>feComposite</a> composites the result of the specular lighting with the original source graphic.
    6. Filter primitive <a element>feMerge</a> composites two layers together. The lower layer consists of the drop shadow result from filter primitive 2. The upper layer consists of the specular lighting result from filter primitive 5.
</ol>
</div>

# Module interactions # {#placement}

This specification defines a set of CSS properties that affect the visual rendering of elements to which those properties are applied; these effects are applied after elements have been sized and positioned according to the <a href="https://www.w3.org/TR/CSS2/visuren.html" lt="Visual formatting model">Visual formatting model</a> from [[!CSS21]]. Some values of these properties result in the creation of a <a>containing block</a>, and/or the creation of a <a>stacking context</a>.

The compositing model follows the SVG compositing model [[!SVG11]]: first any filter effect is applied, then any clipping, masking and opacity [[CSS3COLOR]]. These effects all apply after any other CSS effects such as 'border' [[!CSS3BG]].

Some property and element definitions in this specification require an SVG 1.1 implementation [[!SVG11]]. UAs without support for SVG must not implement the 'color-interpolation-filters', 'flood-color', 'flood-opacity' and 'lighting-color' properties as well as the <a element>filter</a> element, the <a element>feMergeNode</a> element, the <a>transfer function elements</a> and the <a>filter primitive</a> elements.

# Values # {#values}

This specification follows the <a href="https://www.w3.org/TR/CSS21/about.html#property-defs">CSS property definition conventions</a> from [[!CSS21]]. Value types not defined in these specifications are defined in CSS Values and Units Module Level 3 [[!CSS3VAL]].

In addition to the property-specific values listed in their definitions, all properties defined in this specification also accept the <a href="https://www.w3.org/TR/CSS21/cascade.html#value-def-inherit">inherit</a> keyword as their property value. For readability it has not been repeated explicitly.

# Terminology # {#definitions}

When used in this specification, terms have the meanings assigned in this section.

: <dfn>filter primitive</dfn>, <dfn dfn-type=element id="elementdef-filter-primitive">filter-primitive</dfn>
::
    The set of elements that control the output of a <a element>filter</a> element, particularly: <a element>feSpotLight</a>, <a element>feBlend</a>, <a element>feColorMatrix</a>, <a element>feComponentTransfer</a>, <a element>feComposite</a>, <a element>feConvolveMatrix</a>, <a element>feDiffuseLighting</a>, <a element>feDisplacementMap</a>, <a element>feDropShadow</a>, <a element>feFlood</a>, <a element>feGaussianBlur</a>, <a element>feImage</a>, <a element>feMerge</a>, <a element>feMorphology</a>, <a element>feOffset</a>, <a element>feSpecularLighting</a>, <a element>feTile</a>, <a element>feTurbulence</a>.
: <dfn>pass through filter</dfn>
::
    The pass through filter output is equal to the primary input of the filter primitive.

# Graphic filters: the 'filter' property # {#FilterProperty}

The description of the 'filter' property is as follows:

<pre class='propdef'>
Name: filter
Value: none | <<filter-value-list>>
Initial: none
Applies to: All elements. In SVG, it applies to <a>container elements</a> without the <a element>defs</a> element, all <a>graphics elements</a> and the <a element>use</a> element.
Inherited: no
Percentages: n/a
Computed value: as specified
Media: visual
Animation type: See prose in <a href="#animation-of-filters">Animation of Filters</a>.
</pre>

<pre class=prod><dfn>&lt;filter-value-list></dfn> = [ <<filter-function>> | <<filter/url>> <!--| <<child-selector>> -->]+</pre>

<dl dfn-for="filter">
    : <dfn>&lt;url></dfn>
    ::
        A filter reference to a <a element>filter</a> element. For example ''url(commonfilters.svg#filter)''. If the filter references a non-existent object or the referenced object is not a <a element>filter</a> element, then the whole filter chain is ignored. No filter is applied to the object.
    : <<filter-function>>
    ::
        See <a href="#filter-functions">Filter Functions</a>.
    : none
    ::
        No filter effect gets applied.
</dl>

A value other than ''filter/none'' for the 'filter' property results in the creation of a <a>containing block</a> for absolute and fixed positioned descendants unless the element it applies to is a document root element in the current <a>browsing context</a>. The list of functions are applied in the order provided.

The first filter function or <a element>filter</a> reference in the list takes the element (<a attr-value>SourceGraphic</a>) as the input image. Subsequent operations take the output from the previous filter function or <a element>filter</a> reference as the input image. <a element>filter</a> element reference functions can specify an alternate input, but still uses the previous output as its <a attr-value>SourceGraphic</a>.

'color-interpolation-filters' has no affect for Filter Functions. Filter Functions must operate in the sRGB color space.

A computed value of other than ''filter/none'' results in the creation of a <a href="https://www.w3.org/TR/CSS21/zindex.html">stacking context</a> [[!CSS21]] the same way that CSS 'opacity' does. All the elements descendants are rendered together as a group with the filter effect applied to the group as a whole.

The 'filter' property has no effect on the geometry of the target element's CSS boxes,
although 'filter' can contribute to the element's [=ink overflow area=].

Conceptually, any parts of the drawing are effected by filter operations. This includes any content, background, borders, text decoration, outline and visible scrolling mechanism of the element to which the filter is applied, and those of its descendants. The filter operations are applied in the element's <a>local coordinate system</a>.

The compositing model follows the <a href="https://www.w3.org/TR/SVG11/render.html#Introduction">SVG compositing model</a> [[!SVG11]]: first any filter effect is applied, then any clipping, masking and opacity. As per SVG, the application of 'filter' has no effect on hit-testing.

The 'filter' property is a <a href="https://www.w3.org/TR/2011/REC-SVG11-20110816/intro.html#TermPresentationAttribute">presentation attribute</a> for SVG elements.

Issue(238): How does filter behave on fixed background images?

# Filter Functions # {#filter-functions}

## Supported Filter Functions ## {#supported-filter-functions}

<pre class=prod><dfn>&lt;filter-function></dfn> = <<blur()>> | <<brightness()>> | <<contrast()>> | <<drop-shadow()>> | <br>
  <<grayscale()>> | <<hue-rotate()>> | <<invert()>> | <<opacity()>> | <<sepia()>> | <<saturate()>></pre>

Unless defined otherwise, omitted values default to the <a for=svg>initial value</a> for interpolation.

Note: For some filter functions the default value for omitted values differes from their <a for=svg>initial value</a> for interpolation. For the convenience of content creators, the default value for omitted values for <<grayscale()>>, <<sepia()>> and <<invert()>> is ''1'' (apply the effect to 100%) while the <a for=svg>initial value</a> for interpolation is ''0'' (no effect).

<dl id="FilterFunction" dfn-for="filter">
    : <pre class=prod><dfn>blur()</dfn> = blur( <<length>>? )</pre>
    ::
        Applies a Gaussian blur to the input image. The passed parameter defines the value of the standard deviation to the Gaussian function. The parameter is specified a CSS length, but does not accept percentage values. The markup equivalent of this function is <a href="#blurEquivalent">given below</a>.

        Negative values are not allowed.

        Default value when omitted is ''0px''.

        The <a for=svg>initial value</a> for interpolation is ''0px''.

        Note: Standard deviation is different to 'box-shadow' s blur radius.

        The [=ink overflow rectangle=] for a Gaussian blur is the axis-aligned boundary of the area in which the implementation draws the blur.

        Note: A true Gaussian blur has theoretically infinite extent, but in practice all implementations use a finite-area approximation of a Gaussian blur. At the time of writing (January 2024) all major implementations use the familiar three-pass box blur approximation, which has extent:<br> <code>((3 * sqrt(2 * &pi;) / 4) * &sigma;)</code>.

    : <pre class=prod><dfn>brightness()</dfn> = brightness( [ <<number>> |  <<percentage>> ]? )</pre>
    ::
        Applies a linear multiplier to input image, making it appear more or less bright. A value of ''0%'' will create an image that is completely black. A value of ''100%'' leaves the input unchanged. Other values are linear multipliers on the effect. Values of amount over 100% are allowed, providing brighter results. The markup equivalent of this function is <a href="#brightnessEquivalent">given below</a>.

        Negative values are not allowed.

        Default value when omitted is ''1''.

        The <a for=svg>initial value</a> for interpolation is ''1''.
    : <pre class=prod><dfn>contrast()</dfn> = contrast( [ <<number>> |  <<percentage>> ]? )</pre>
    ::
        Adjusts the contrast of the input. A value of ''0%'' will create an image that is completely gray. A value of ''100%'' leaves the input unchanged. Values of amount over 100% are allowed, providing results with more contrast. The markup equivalent of this function is <a href="#contrastEquivalent">given below</a>.

        Negative values are not allowed.

        Default value when omitted is ''1''.

        The <a for=svg>initial value</a> for interpolation is ''1''.
    : <pre class=prod><dfn>drop-shadow()</dfn> = drop-shadow( [ <<color>>? && <<length>>{2,3} ] )</pre>
    ::
        Applies a drop shadow effect to the input image. A drop shadow is effectively a blurred, offset version of the input image's alpha mask drawn in a particular color, composited below the image. Values are interpreted as for 'box-shadow' [[!CSS3BG]] but with the optional 3rd <<length>> value being the standard deviation instead of blur radius. The markup equivalent of this function is <a href="#dropshadowEquivalent">given below</a>.

        The default value for omitted values is missing length values set to ''0'' and the missing used color is taken from the color property.

        The <a for=svg>initial value</a> for interpolation is all length values set to ''0'' and the used color set to ''transparent''.

        Note: Spread values or multiple shadows are not accepted for this level of the specification.

        Note: Standard deviation is different to 'box-shadow' s blur radius.

        The [=ink overflow rectangle=] for a drop shadow is the extent of the offsets,
        plus the extent of the blur (if any) as described for <<blur()>>.

    : <pre class=prod><dfn>grayscale()</dfn> = grayscale( [ <<number>> |  <<percentage>> ]? )</pre>
    ::
        Converts the input image to grayscale. The passed parameter defines the proportion of the conversion. A value of ''100%'' is completely grayscale. A value of ''0%'' leaves the input unchanged. Values between ''0%'' and ''100%'' are linear multipliers on the effect. Values of amount over ''100%'' are allowed but UAs must clamp the values to ''1''. The markup equivalent of this function is <a href="#grayscaleEquivalent">given below</a>.

        Negative values are not allowed.

        Default value when omitted is ''1''.

        The <a for=svg>initial value</a> for interpolation is ''0''.

    : <pre class=prod><dfn>hue-rotate()</dfn> = hue-rotate( [ <<angle>> | <<zero>> ]? )</pre>
    ::
        Applies a hue rotation on the input image. The passed parameter defines the number of degrees around the color circle the input samples will be adjusted. A value of ''0deg'' leaves the input unchanged. Implementations must not normalize this value in order to allow animations beyond ''360deg''. The markup equivalent of this function is <a href="#huerotateEquivalent">given below</a>.

        The unit identifier may be omitted if the <<angle>> is zero.

        Default value when omitted is ''0deg''.

        The <a for=svg>initial value</a> for interpolation is ''0deg''.
    : <pre class=prod><dfn>invert()</dfn> = invert( [ <<number>> |  <<percentage>> ]? )</pre>
    ::
        Inverts the samples in the input image. The passed parameter defines the proportion of the conversion. A value of 100% is completely inverted. A value of ''0%'' leaves the input unchanged. Values between ''0%'' and ''100%'' are linear multipliers on the effect. Values of amount over ''100%'' are allowed but UAs must clamp the values to ''1''. The markup equivalent of this function is <a href="#invertEquivalent">given below</a>.

        Negative values are not allowed.

        Default value when omitted is ''1''.

        The <a for=svg>initial value</a> for interpolation is ''0''.
    : <pre class=prod><dfn>opacity()</dfn> = opacity( [ <<number>> |  <<percentage>> ]? )</pre>
    ::
        Applies transparency to the samples in the input image. The passed parameter defines the proportion of the conversion. A value of ''0%'' is completely transparent. A value of ''100%'' leaves the input unchanged. Values between ''0%'' and ''100%'' are linear multipliers on the effect. This is equivalent to multiplying the input image samples by amount. Values of amount over ''100%'' are allowed but UAs must clamp the values to ''1''. The markup equivalent of this function is <a href="#opacityEquivalent">given below</a>.

        Negative values are not allowed.

        Default value when omitted is ''1''.

        The <a for=svg>initial value</a> for interpolation is ''1''.

        Note: The opacity filter function is not meant to be a shorthand of the 'opacity' property. Furthermore, it allows setting the transparency of intermediate filter primitive results before passing to the next filter primitive. If the opacity filter function is set as last filter primitive, the value of the 'opacity' property is multiplied on top of the value of the filter function, which may result in a more transparent content.

    : <pre class=prod><dfn>saturate()</dfn> = saturate( [ <<number>> |  <<percentage>> ]? )</pre>
    ::
        Saturates the input image. The passed parameter defines the proportion of the conversion. A value of ''0%'' is completely un-saturated. A value of ''100%'' leaves the input unchanged. Other values are linear multipliers on the effect. Values of amount over ''100%'' are allowed, providing super-saturated results. The markup equivalent of this function is <a href="#saturateEquivalent">given below</a>.

        Negative values are not allowed.

        Default value when omitted is ''1''.

        The <a for=svg>initial value</a> for interpolation is ''1''.
    : <pre class=prod><dfn>sepia()</dfn> = sepia( [ <<number>> |  <<percentage>> ]? )</pre>
    ::
        Converts the input image to sepia. The passed parameter defines the proportion of the conversion. A value of ''100%'' is completely sepia. A value of ''0%'' leaves the input unchanged. Values between 0% and 100% are linear multipliers on the effect. Values of amount over ''100%'' are allowed but UAs must clamp the values to ''1''. The markup equivalent of this function is <a href="#sepiaEquivalent">given below</a>.

        Negative values are not allowed.

        Default value when omitted is ''1''.

        The <a for=svg>initial value</a> for interpolation is ''0''.
</dl>

## Computed Values of Filter Functions ## {#computed-values-of-filter-functions}

The values in a <<filter-function>> are computed as specified, with these exceptions:

* Omitted values are included and compute to their defaults.
* <<drop-shadow()>> starts with the computed value of <<color>> followed by the computed value of the <<length>> values.

## Serialization of Filter Functions ## {#serialization-of-filter-functions}

To serialize the <<filter-function>>, serialize as per their individual grammars, in the order the grammars are written in, avoiding <<calc()>> expressions where possible, serialize filter arguments as specified, avoiding <<calc()>> transformations, joining space-separated tokens with a single space, and following each serialized comma with a single space.

## Interpolation of Filter Functions ## {#interpolation-of-filter-functions}

For interpolation of values in <<filter-function>>s, the steps corresponding to the first matching condition in the following list must be run:

<dl class=switch>
    : <<blur()>>
    :: Interpolate values as [[css3-transitions#animtype-length|length]].
    : <<brightness()>>
    : <<contrast()>>
    : <<grayscale()>>
    : <<invert()>>
    : <<opacity()>>
    : <<saturate()>>
    : <<sepia()>>
    :: Convert percentage values to numbers with 0% being relative to 0 and 100% relative to 1. Interpolate values [[css3-transitions#animtype-number|number]].
    : <<hue-rotate()>>
    :: Interpolate values as [[css3-transitions#animtype-number|number]].
    : <<drop-shadow()>>
    :: Interpolate values as [[css3-transitions#animtype-shadow-list|shadow list]].
</dl>

# SVG Filter Sources: the <a element>filter</a> element # {#FilterElement}

<pre class=include>
path: templates/filter.md
</pre>

The description of the <a element>filter</a> element follows:

<dfn>&lt;number-optional-number></dfn> = <<number>> <<number>>?

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=filter>
    : <dfn>filterUnits</dfn> = "<dfn attr-value for=filterUnits>userSpaceOnUse</dfn> | <dfn attr-value for=filterUnits>objectBoundingBox</dfn>"
    :: See <a>filter region</a>.
    : <dfn>primitiveUnits</dfn> = "<dfn attr-value for=primitiveUnits>userSpaceOnUse</dfn> | <dfn attr-value for=primitiveUnits>objectBoundingBox</dfn>"
    ::
        Specifies the coordinate system for the various length values within the <a>filter primitives</a> and for the attributes that define the <a>filter primitive subregion</a>.

        If <a element-attr>primitiveUnits</a> is equal to <a attr-value for=primitiveUnits>userSpaceOnUse</a>, any length values within the filter definitions represent values in the current <a>local coordinate system</a> in place at the time when the <a element>filter</a> element is referenced (i.e., the user coordinate system for the element referencing the <a element>filter</a> element via a 'filter' property).

        If <a element-attr>primitiveUnits</a> is equal to <a attr-value for=primitiveUnits>objectBoundingBox</a>, then any length values within the filter definitions represent fractions or percentages of the bounding box on the referencing element (see <a>object bounding box units</a>). Note that if only one number was specified in a <<number-optional-number>> value this number is expanded out before the <a element-attr>primitiveUnits</a> computation takes place.

        The <a for=svg>initial value</a> for <a element-attr>primitiveUnits</a> is <a attr-value for=primitiveUnits>userSpaceOnUse</a>.

        Animatable: yes.
    : <dfn>x</dfn> = "<<length-percentage>>"
    :: See <a>filter region</a>.
    : <dfn>y</dfn> = "<<length-percentage>>"
    :: See <a>filter region</a>.
    : <dfn>width</dfn> = "<<length-percentage>>"
    :: See <a>filter region</a>.
    : <dfn>height</dfn> = "<<length-percentage>>"
    :: See <a>filter region</a>.
    : <dfn>filterRes</dfn> = "<<number-optional-number>>"
    :: The <em>filterRes</em> attribute was removed from the specification. See SVG 1.1 specification for the defintion [[!SVG11]].
</dl>

Properties inherit into the <a element>filter</a> element from its ancestors; properties do <em>not</em> inherit from the element referencing the <a element>filter</a> element.

<a element>filter</a> elements are never rendered directly; their only usage is as something that can be referenced using the 'filter' property. The 'display' property does not apply to the <a element>filter</a> element; thus, <a element>filter</a> elements are not directly rendered even if the 'display' property is set to a value other than ''filter/none'', and <a element>filter</a> elements are available for referencing even when the 'display' property on the <a element>filter</a> element or any of its ancestors is set to ''filter/none''.

# Filter Region # {#FilterEffectsRegion}

A <a element>filter</a> element can define a <dfn>filter region</dfn> on the canvas to which a given filter effect applies and can provide a resolution for any intermediate continuous tone images used to process any raster-based <a>filter primitives</a>. The <a element>filter</a> element has the following attributes which work together to define the filter region:

<dl class='definitions unemphasized-names'>
  : <a element-attr>filterUnits</a>
  ::
      Defines the coordinate system for attributes <a element-attr for=filter>x</a>, <a element-attr for=filter>y</a>, <a element-attr for=filter>width</a>, <a element-attr for=filter>height</a>.

      If <a element-attr for=filter>filterUnits</a> is equal to <a attr-value for=filterUnits>userSpaceOnUse</a>, <a element-attr for=filter>x</a>, <a element-attr for=filter>y</a>, <a element-attr for=filter>width</a>, <a element-attr for=filter>height</a> represent values in the current user coordinate system in place at the time when the <a element>filter</a> element is referenced (i.e., the user coordinate system for the element referencing the <a element>filter</a> element via a 'filter' property).

      If <a element-attr for=filter>filterUnits</a> is equal to <a attr-value for=filterUnits>objectBoundingBox</a>, then <a element-attr for=filter>x</a>, <a element-attr for=filter>y</a>, <a element-attr for=filter>width</a>, <a element-attr for=filter>height</a> represent fractions or percentages of the bounding box on the referencing element (see <a>object bounding box units</a>).

      The <a for=svg>initial value</a> for <a element-attr>filterUnits</a> is <a attr-value for=filterUnits>objectBoundingBox</a>.

      Animatable: yes.
  : <a element-attr for=filter>x</a>, <a element-attr for=filter>y</a>, <a element-attr for=filter>width</a>, <a element-attr for=filter>height</a>
  ::
      These attributes define a rectangular region on the canvas to which this filter applies.

      The coordinate system for these attributes depends on the value for attribute <a element-attr>filterUnits</a>.

      The bounds of this rectangle act as a hard clipping region for each <a>filter primitive</a> included with a given <a element>filter</a> element; thus, if the effect of a given filter primitive would extend beyond the bounds of the rectangle (this sometimes happens when using a <a element>feGaussianBlur</a> filter primitive with a very large <a element-attr for=feGaussianBlur>stdDeviation</a>), parts of the effect will get clipped.

      The <a for=svg>initial value</a> for <a element-attr for=filter>x</a> and <a element-attr for=filter>y</a> is ''-10%''.

      The <a for=svg>initial value</a> for <a element-attr for=filter>width</a> and <a element-attr for=filter>height</a> is ''120%''.

      ng of the element which referenced the filter.

      Animatable: yes.

</dl>

Note: Both of the two possible value for <a element-attr>filterUnits</a> (i.e., <a attr-value for=filterUnits>objectBoundingBox</a> and <a attr-value for=filterUnits>userSpaceOnUse</a>) result in a <a>filter region</a> whose coordinate system has its X-axis and Y-axis each parallel to the X-axis and Y-axis, respectively, of the <a>local coordinate system</a> for the element to which the filter will be applied.

Note: Sometimes implementers can achieve faster performance when the filter region can be mapped directly to device pixels; thus, for best performance on display devices, it is suggested that authors define their region such that the user agent can align the <a>filter region</a> pixel-for-pixel with the background. In particular, for best filter effects performance, avoid rotating or skewing the user coordinate system.

Note: It is often necessary to provide padding space because the filter effect might impact bits slightly outside the tight-fitting <a>bounding box</a> on a given object. For these purposes, it is possible to provide negative percentage values for <a element-attr for=filter>x</a>, <a element-attr for=filter>y</a> and percentages values greater than ''100%'' for <a element-attr for=filter>width</a>, <a element-attr for=filter>height</a>. This, for example, is why the defaults for the filter region are <code>x="-10%" y="-10%" width="120%" height="120%"</code>.

# Filter primitives # {#FilterPrimitivesOverview}

## Overview ## {#FilterPrimitivesOverviewIntro}

This section describes the various filter primitives that can be assembled to achieve a particular filter effect.

Unless otherwise stated, all image filters operate on premultiplied RGBA samples. Some filters like <a element>feColorMatrix</a> and <a element>feComponentTransfer</a> work more naturally on non-premultiplied data. For the time of the filter operation, all color values must temporarily be transformed to the required color multiplication of the current filter.

Note: All input images are assumed to be in premultiplied RGBA. User agents may optimize performance by using non-premultiplied data buffering.

All raster effect filtering operations take 1 to N input RGBA images, additional attributes as parameters, and produce a single output RGBA image.

The RGBA result from each filter primitive will be clamped into the allowable ranges for colors and opacity values. Thus, for example, the result from a given <a>filter primitive</a> will have any negative color values or opacity values adjusted up to color/opacity of zero.

<p id="filtersColorSpace">The color space in which a particular <a>filter primitive</a> performs its operations is determined by the value of the property 'color-interpolation-filters' on the given <a>filter primitive</a>. A different property, 'color-interpolation' determines the color space for other color operations. Because these two properties have different initial values ('color-interpolation-filters' has an initial value of ''linearRGB'' whereas 'color-interpolation' has an initial value of ''sRGB''), in some cases to achieve certain results (e.g., when coordinating gradient interpolation with a filtering operation) it will be necessary to explicitly set 'color-interpolation' to ''linearRGB'' or 'color-interpolation-filters' to ''sRGB'' on particular elements. Note that the examples below do not explicitly set either 'color-interpolation' or 'color-interpolation-filters', so the initial values for these properties apply to the examples.</p>

Sometimes <a>filter primitives</a> result in undefined pixels. For example, filter primitive <a element>feOffset</a> can shift an image down and to the right, leaving undefined pixels at the top and left. In these cases, the undefined pixels are set to transparent black.

To provide high quality rendering, all filter primitives should operate in a device dependent coordinate space, the <dfn>operating coordinate space</dfn>, taking device pixel density, user space transformations and zooming into account. To provide a platform independent alignment, attribute and property values are often relative to a coordinate system described by the <a element-attr>primitiveUnits</a> attribute. User agents must scale these relative attributes and properties to the <a>operating coordinate space</a>.

Note: On high resolution devices, attribute and property values that are relative to the <a element-attr>primitiveUnits</a> usually need to be scaled up. User agents may reduce the resolution of filter primitives on limited platform resources.

Note: Some attribute or property values from the filter primitives <a element>feConvolveMatrix</a> and <a>light sources</a> can not be mapped from the coordinate space defined by the <a element-attr>primitiveUnits</a> attribute to the <a>operating coordinate space</a>.

## Common filter primitive attributes ## {#CommonAttributes}

The following <dfn id="filter-primitive-attributes">filter primitive attributes</dfn> are available for all filter primitives:

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=filter-primitive>
    : <dfn>x</dfn> = "<<length-percentage>>"
    ::
        The minimum x coordinate for the subregion which restricts calculation and rendering of the given <a>filter primitive</a>. See <a>filter primitive subregion</a>.

        The <a for=svg>initial value</a> for <a element-attr for=filter-primitive>x</a> is ''0%''.

        Animatable: yes.
    : <dfn>y</dfn> = "<<length-percentage>>"
    ::
        The minimum y coordinate for the subregion which restricts calculation and rendering of the given <a>filter primitive</a>. See <a>filter primitive subregion</a>.

        The <a for=svg>initial value</a> for <a element-attr for=filter-primitive>y</a> is ''0%''.

        Animatable: yes.
    : <dfn>width</dfn> = "<<length-percentage>>"
    ::
        The width of the subregion which restricts calculation and rendering of the given <a>filter primitive</a>. See <a>filter primitive subregion</a>.

        A negative or zero value disables the effect of the given filter primitive (i.e., the result is a transparent black image).

        The <a for=svg>initial value</a> for <a element-attr for=filter-primitive>width</a> is ''100%''.

        Animatable: yes.
    : <dfn>height</dfn> = "<<length-percentage>>"
    ::
        The height of the subregion which restricts calculation and rendering of the given <a>filter primitive</a>. See <a>filter primitive subregion</a>.

        A negative or zero value must disable the effect of the given filter primitive (i.e., the result is a transparent black image).

        The <a for=svg>initial value</a> for <a element-attr for=filter-primitive>height</a> is ''100%''.

        Animatable: yes.
    : <dfn>result</dfn> = "<em><dfn type dfn-for=result>&lt;filter-primitive-reference></dfn></em>"
    ::
        <<filter-primitive-reference>> is an <<custom-ident>> [[CSS3VAL]] and an assigned name for this <a>filter primitive</a>. If supplied, then graphics that result from processing this <a>filter primitive</a> can be referenced by an <a element-attr>in</a> attribute on a subsequent filter primitive within the same <a element>filter</a> element. If no value is provided, the output will only be available for re-use as the implicit input into the next <a>filter primitive</a> if that <a>filter primitive</a> provides no value for its <a element-attr>in</a> attribute.

</dl>

Most filter primitives take other filter primitives as input. The following attribute is representative for all input attributes to reference other filter primitives:

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=filter-primitive>
    : <dfn>in</dfn> = "<em><a attr-value>SourceGraphic</a> | <a attr-value>SourceAlpha</a> | <a attr-value>BackgroundImage</a> | <a attr-value>BackgroundAlpha</a> | <a attr-value>FillPaint</a> | <a attr-value>StrokePaint</a> | <<filter-primitive-reference>></em>"
    ::
        Identifies input for the given filter primitive. The value can be either one of six keywords or can be a string which matches a previous <a element-attr>result</a> attribute value within the same <a element>filter</a> element. If no value is provided and this is the first <a>filter primitive</a>, then this <a>filter primitive</a> will use <a attr-value>SourceGraphic</a> as its input. If no value is provided and this is a subsequent <a>filter primitive</a>, then this <a>filter primitive</a> will use the result from the previous <a>filter primitive</a> as its input.

        If the value for <a element-attr for=filter-primitive>result</a> appears multiple times within a given <a element>filter</a> element, then a reference to that result will use the closest preceding <a>filter primitive</a> with the given value for attribute <a element-attr>result</a>.

        Forward references to results are not allowed, and will be treated as if no result was specified.

        References to non-existent results will be treated as if no result was specified.

        Definitions for the six keywords:
        <dl dfn-type=attr-value dfn-for=in>
            : <dfn>SourceGraphic</dfn>
            ::
                This keyword represents the graphics elements that were the original input into the <a element>filter</a> element. For raster effects <a>filter primitives</a>, the graphics elements will be rasterized into  an initially clear RGBA raster in image space. Pixels left untouched by the original graphic will be left clear. The image is specified to be rendered in linear RGBA pixels. The alpha channel of this image captures any anti-aliasing specified by SVG. (Since the raster is linear, the alpha channel of this image will represent the exact percent coverage of each pixel.)
            : <dfn>SourceAlpha</dfn>
            ::
                This keyword represents the graphics elements that were the original input into the <a element>filter</a> element. <a attr-value>SourceAlpha</a> has all of the same rules as <a attr-value>SourceGraphic</a> except that only the alpha channel is used. The input image is an RGBA image consisting of implicitly black color values for the RGB channels, but whose alpha channel is the same as <a attr-value>SourceGraphic</a>.

                Note: If this option is used, then some implementations might need to rasterize the graphics elements in order to extract the alpha channel.
            : <dfn>BackgroundImage</dfn>
            ::
                This keyword represents the back drop defined by the current isolation group behind the <a>filter region</a> at the time that the <a element>filter</a> element was invoked. See 'isolation' property [[!COMPOSITING-1]].
            : <dfn>BackgroundAlpha</dfn>
            ::
                Same as <a attr-value>BackgroundImage</a> except only the alpha channel is used. See <a attr-value>SourceAlpha</a> and the 'isolation' property [[!COMPOSITING-1]].
            : <dfn>FillPaint</dfn>
            ::
                This keyword represents the value of the 'fill' property on the target element for the filter effect. The <a attr-value>FillPaint</a> image has conceptually infinite extent. Frequently this image is opaque everywhere, but it might not be if the "paint" itself has alpha, as in the case of a gradient or pattern which itself includes transparent or semi-transparent parts. If 'fill' references a paint server, then the coordinate space of the paint server is the coordinate space defined for the filtered object. E.g if the paint server requires to use the <a attr-value for=primitiveUnits>objectBoundingBox</a> of the object, the object bounding box of the filtered object defines the reference size of the paint server. If the paint server requires to use the <a attr-value for=primitiveUnits>userSpaceOnUse</a>, the nearest viewport in the <a>local coordinate system</a> of the filtered object defines the reference size of the paint server.
            : <dfn>StrokePaint</dfn>
            ::
                This keyword represents the value of the 'stroke' property on the target element for the filter effect. The <a attr-value>StrokePaint</a> image has conceptually infinite extent. See <a attr-value>FillPaint</a> above for more details.
        </dl>
        Animatable: yes.
</dl>

## Filter primitive tree ## {#FilterPrimitiveTree}

Filter primitives with no or one filter primitive input can be linked together to a filter chain. E.g. the filter primitive representation of a <<filter-value-list>> with two or more <<filter-function>>s is an example of a filter chain. Every filter primitive takes the result of the previous filter primitive as input.

<div class=example>
    A simple example of a <a element>filter</a> element with its filter primitive children.
    <pre><code highlight=svg>
        &lt;filter id="filter">
          &lt;feColorMatrix type="hueRotate" values="45"/>
          &lt;feOffset dx="10" dy="10"/>
          &lt;feGaussianBlur stdDeviation="3"/>
        &lt;/filter>
    </code></pre>

    <a element>feColorMatrix</a>, <a element>feOffset</a> and <a element>feGaussianBlur</a> create a filter chain.

    <a element>feColorMatrix</a> takes ''SourceGraphic'' as input. The result is the input of <a element>feOffset</a> with its result being the input of <a element>feGaussianBlur</a>.
</div>

Some filter primitives may have more than one filter primitive inputs. With the use of the <a element-attr>in</a> and <a element-attr>result</a> attributes it is possible to combine multiple filter primitives to a complex filter structure. Due to the non-forward reference restriction of filter primitives, every filter structure can be represented as a tree, the <dfn data-export>filter primitive tree</dfn>. The root filter primitive of the filter primitive tree is the most subsequential primitive of <a element>filter</a> elements filter primitive children.

A filter chain is one possible filter structure that can also be represented in a filter primitive tree. Therefore, filter chains are referred to as filter primitive trees onwards as well.

A <a element>filter</a> element may have one or more filter primitive trees. The filter primitive tree whose subsequent filter primitive is the last filter primitive child of the <a element>filter</a> elements is the <dfn data-export>primary filter primitive tree</dfn>.

Only the primary filter primitive tree contributes to the filter process. Implementations may chose to ignore all other possible filter primitive trees.

If a <a element>filter</a> element has no filter primitive tree then the element the filter applies to does not get rendered.

<div class=example>
    An example of multiple filter primitive trees:
    <pre><code highlight=svg>
        &lt;filter id="filter">
          &lt;!-- The first filter primitive tree. Ignored for filter process. -->
          &lt;feColorMatrix type="hueRotate" values="45"/>
          &lt;feOffset dx="10" dy="10"/>
          &lt;feGaussianBlur stdDeviation="3"/>
          &lt;!-- The primary filter primitive tree. -->
          &lt;feFlood flood-color="green" result="flood"/>
          &lt;feComposite operator="in" in="SourceAlpha" in2="flood"/>
        &lt;/filter>
    </code></pre>

    The above filter has 2 filter primitive trees with the filter primitives:
    1. <a element>feColorMatrix</a>, <a element>feOffset</a> and <a element>feGaussianBlur</a> (with <a element>feGaussianBlur</a> being the root filter primitive of the tree) as well as
    2. <a element>feFlood</a> and <a element>feComposite</a> (with <a element>feComposite</a> as the root filter primitive of the tree).

    Both filter primitive trees are not connected. Only the 2nd, the primary filter primitive tree contributes to the filter process. The first tree can get ignored by implementations.
</div>

## Filter primitive subregion ## {#FilterPrimitiveSubRegion}

All <a>filter primitives</a> have attributes <a element-attr for=filter-primitive>x</a>, <a element-attr for=filter-primitive>y</a>, <a element-attr for=filter-primitive>width</a> and <a element-attr for=filter-primitive>height</a> which together identify a <dfn id="filter-primitive-subregion">filter primitive subregion</dfn> which restricts calculation and rendering of the given <a>filter primitive</a>. The <a element-attr for=filter-primitive>x</a>, <a element-attr for=filter-primitive>y</a>, <a element-attr for=filter-primitive>width</a> and <a element-attr for=filter-primitive>height</a> attributes are defined according to the same rules as other <a>filter primitives</a> coordinate and length attributes and thus represent values in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element.

<a element-attr for=filter-primitive>x</a>, <a element-attr for=filter-primitive>y</a>, <a element-attr for=filter-primitive>width</a> and <a element-attr for=filter-primitive>height</a> default to the union (i.e., tightest fitting bounding box) of the subregions defined for all referenced nodes. If there are no referenced nodes (e.g., for <a element>feImage</a> or <a element>feTurbulence</a>), or one or more of the referenced nodes is a standard input (one of <a attr-value>SourceGraphic</a>, <a attr-value>SourceAlpha</a>, <a attr-value>BackgroundImage</a>, <a attr-value>BackgroundAlpha</a>, <a attr-value>FillPaint</a> or <a attr-value>StrokePaint</a>), or for <a element>feTile</a> (which is special because its principal function is to replicate the referenced node in X and Y and thereby produce a usually larger result), the default subregion is ''0%, 0%, 100%, 100%'', where as a special-case the percentages are relative to the dimensions of the <a>filter region</a>, thus making the default <a>filter primitive subregion</a> equal to the <a>filter region</a>.

If the <a>filter primitive subregion</a> has a negative or zero width or height, the effect of the filter primitive is disabled.

The <a>filter region</a> acts as a hard clip clipping rectangle on the filter primitive's input image(s).

The <a>filter primitive subregion</a> acts as a hard clip clipping rectangle on the filter primitive result.

All intermediate offscreens are defined to not exceed the intersection of the <a>filter primitive subregion</a> with the <a>filter region</a>. The <a>filter region</a> and any of the filter primitive subregions are to be set up such that all offscreens are made big enough to accommodate any pixels which even partly intersect with either the <a>filter region</a> or the filter primitive subregions.

<div class=example>
    <a element>feTile</a> references a previous filter primitive and then stitches the tiles together based on the <a>filter primitive subregion</a> of the referenced filter primitive in order to fill its own <a>filter primitive subregion</a>.

    <pre><code highlight=svg>
        &lt;svg width="400" height="400" xmlns="http://www.w3.org/2000/svg"&gt;
          &lt;defs&gt;
            &lt;filter id="flood" x="0" y="0" width="100%" height="100%" primitiveUnits="objectBoundingBox"&gt;
               &lt;feFlood x="25%" y="25%" width="50%" height="50%"
                  flood-color="green" flood-opacity="0.75"/&gt;
            &lt;/filter&gt;
            &lt;filter id="blend" primitiveUnits="objectBoundingBox"&gt;
               &lt;feBlend x="25%" y="25%" width="50%" height="50%"
                  in2="SourceGraphic" mode="multiply"/&gt;
            &lt;/filter&gt;
            &lt;filter id="merge" primitiveUnits="objectBoundingBox"&gt;
               &lt;feMerge x="25%" y="25%" width="50%" height="50%"&gt;
                &lt;feMergeNode in="SourceGraphic"/&gt;
                &lt;feMergeNode in="FillPaint"/&gt;
               &lt;/feMerge&gt;
            &lt;/filter&gt;
          &lt;/defs&gt;

          &lt;g fill="none" stroke="blue" stroke-width="4"&gt;
             &lt;rect width="200" height="200"/&gt;
             &lt;line x2="200" y2="200"/&gt;
             &lt;line x1="200" y2="200"/&gt;
          &lt;/g&gt;
          &lt;circle fill="green" filter="url(#flood)" cx="100" cy="100" r="90"/&gt;

          &lt;g transform="translate(200 0)"&gt;
            &lt;g fill="none" stroke="blue" stroke-width="4"&gt;
               &lt;rect width="200" height="200"/&gt;
               &lt;line x2="200" y2="200"/&gt;
               &lt;line x1="200" y2="200"/&gt;
            &lt;/g&gt;
            &lt;circle fill="green" filter="url(#blend)" cx="100" cy="100" r="90"/&gt;
          &lt;/g&gt;

          &lt;g transform="translate(0 200)"&gt;
            &lt;g fill="none" stroke="blue" stroke-width="4"&gt;
               &lt;rect width="200" height="200"/&gt;
               &lt;line x2="200" y2="200"/&gt;
               &lt;line x1="200" y2="200"/&gt;
            &lt;/g&gt;
            &lt;circle fill="green" fill-opacity="0.5" filter="url(#merge)" cx="100" cy="100" r="90"/&gt;
          &lt;/g&gt;
        &lt;/svg&gt;
    </code></pre>

    <div class=figure>
        <img alt="Example for subregions" src="examples/filtersubregion00.png">
        <p class=caption>Example for subregions</p>
    </div>

    <a href="examples/filtersubregion00.svg">View this example as SVG</a>

    In the example above there are three rectangles that each have a cross and a circle in them. The circle element in each one has a different filter applied, but with the same <a>filter primitive subregion</a>. The filter output should be limited to the <a>filter primitive subregion</a> so you should never see the circles themselves, just the rectangles that make up the <a>filter primitive subregion</a>.
    * The upper left rectangle shows an <a element>feFlood</a> with ''flood-opacity: 75%'' so the cross should be visible through the green rect in the middle.
    * The lower left rectangle shows an <a element>feMerge</a> that merges <a attr-value>SourceGraphic</a> with <a attr-value>FillPaint</a>. Since the circle has <code>fill-opacity="0.5"</code> it will also be transparent so that the cross is visible through the green rect in the middle.
    * The upper right rectangle shows an <a element>feBlend</a> that has <code>mode="multiply"</code>. Since the circle in this case isn't transparent the result is totally opaque. The rect should be dark green and the cross should not be visible through it.
</div>

## Filter primitive <a element>feBlend</a> ## {#feBlendElement}

<pre class=include>
path: templates/effect-in2.md
macros:
    name: feBlend
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFEBlendElement
    attributes: <li><a element-attr for=feBlend>mode</a></li>
</pre>

This filter blends two objects together using commonly used imaging software blending modes. It performs a pixel-wise combination of two input images. (See [[COMPOSITING-1]].)

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feBlend>
    : <dfn>mode</dfn> = "<<blend-mode>>"
    ::
        One of the blend modes defined by “Compositing and Blending Level 1” [[!COMPOSITING-1]] with the input <a element-attr>in</a> representing the source <code>Cs</code> and the second input <a element-attr for=feBlend>in2</a> representing the <a>backdrop</a> <code>Cb</code>. The output of this filter primitive <code>Cm</code> is the result of blending <code>Cs</code> with <code>Cb</code>.

        The <a for=svg>initial value</a> for <a element-attr>mode</a> is ''normal''.

        Animatable: yes.
    : <dfn>no-composite</dfn> = "<dfn attr-value for=no-composite>no-composite</dfn>"
    ::
        If the <a element-attr>no-composite</a> attribute is present, the specified blend mode must not apply alpha compositing. See [[compositing-1#blending|Blending]] [[!COMPOSITING-1]] for the "mixing" formula without compositing. Otherwise, implementations must combine the blend mode specified by <a element-attr>mode</a> with the [[compositing-1#porterduffcompositingoperators_srcover|Source Over]] composite operator. See [[compositing-1#blending|Blending]] [[!COMPOSITING-1]] for the "mixing" formula with compositing.

        Note: This attribute is an addition to the <a element>feBlend</a> element defintion in SVG 1.1. <a element-attr>no-composite</a>, when specified, is meant to avoid "double-compositing" effects when blending an input source with the backdrop of the filtered object (E.g. using the <a attr-value>BackgroundImage</a> filter primitive). For the majority of use cases authors will not need to specify the <a element-attr>no-composite</a> attribute.

        Animatable: no.
    : <dfn>in2</dfn> = "<em>(see <a element-attr>in</a> attribute)</em>"
    ::
        The second input image to the blending operation.

        Animatable: yes.
</dl>

The ''normal'' blend mode with alpha compositing is equivalent to <code>operator="over"</code> on the <a element>feComposite</a> filter primitive, matches the blending method used by <a element>feMerge</a> and matches the <a>simple alpha compositing</a> technique used in SVG for all compositing outside of filter effects.

<div class=example>
    <pre><code highlight=svg>
        &lt;svg width="5cm" height="5cm" viewBox="0 0 500 500"
             xmlns="http://www.w3.org/2000/svg"&gt;
          &lt;title&gt;Example feBlend - Examples of feBlend modes&lt;/title&gt;
          &lt;desc&gt;Five text strings blended into a gradient,
                with one text string for each of the five feBlend modes.&lt;/desc&gt;
          &lt;defs&gt;
            &lt;linearGradient id="MyGradient" gradientUnits="userSpaceOnUse"
                    x1="100" y1="0" x2="300" y2="0"&gt;
              &lt;stop offset="0" stop-color="#000000" /&gt;
              &lt;stop offset=".33" stop-color="#ffffff" /&gt;
              &lt;stop offset=".67" stop-color="#ff0000" /&gt;
              &lt;stop offset="1" stop-color="#808080" /&gt;
            &lt;/linearGradient&gt;
            &lt;filter id="Normal"&gt;
              &lt;feBlend mode="normal" in2="BackgroundImage" in="SourceGraphic"/&gt;
            &lt;/filter&gt;
            &lt;filter id="Multiply"&gt;
              &lt;feBlend mode="multiply" in2="BackgroundImage" in="SourceGraphic"/&gt;
            &lt;/filter&gt;
            &lt;filter id="Screen"&gt;
              &lt;feBlend mode="screen" in2="BackgroundImage" in="SourceGraphic"/&gt;
            &lt;/filter&gt;
            &lt;filter id="Darken"&gt;
              &lt;feBlend mode="darken" in2="BackgroundImage" in="SourceGraphic"/&gt;
            &lt;/filter&gt;
            &lt;filter id="Lighten"&gt;
              &lt;feBlend mode="lighten" in2="BackgroundImage" in="SourceGraphic"/&gt;
            &lt;/filter&gt;
          &lt;/defs&gt;
          &lt;rect fill="none" stroke="blue"
                x="1" y="1" width="498" height="498"/&gt;
          &lt;g isolation="isolate" &gt;
            &lt;rect x="100" y="20" width="300" height="460" fill="url(#MyGradient)" /&gt;
            &lt;g font-family="Verdana" font-size="75" fill="#888888" fill-opacity=".6" &gt;
              &lt;text x="50" y="90" filter="url(#Normal)" &gt;Normal&lt;/text&gt;
              &lt;text x="50" y="180" filter="url(#Multiply)" &gt;Multiply&lt;/text&gt;
              &lt;text x="50" y="270" filter="url(#Screen)" &gt;Screen&lt;/text&gt;
              &lt;text x="50" y="360" filter="url(#Darken)" &gt;Darken&lt;/text&gt;
              &lt;text x="50" y="450" filter="url(#Lighten)" &gt;Lighten&lt;/text&gt;
            &lt;/g&gt;
          &lt;/g&gt;
        &lt;/svg&gt;
    </code></pre>

    <div class=figure>
        <img alt="Example of feBlend" src="examples/feBlend.png">
        <p class=caption>Example of feBlend</p>
    </div>

    <a href="examples/feBlend.svg">View this example as SVG</a>
</div>

## Filter primitive <a element>feColorMatrix</a> ## {#feColorMatrixElement}

<pre class=include>
path: templates/effect-in1.md
macros:
    name: feColorMatrix
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFEColorMatrixElement
    attributes: <li><a element-attr for=feColorMatrix>type</a></li><li><a element-attr for=feColorMatrix>values</a></li>
</pre>

This filter applies a matrix transformation:

<pre class=include>path: mathml/feColorMatrix00.mml</pre>
<!--<object data="mathml/feColorMatrix00.mml" type="application/mathml+xml" width="100%" height="140">
<pre>| R' |     | a00 a01 a02 a03 a04 |   | R |
| G' |     | a10 a11 a12 a13 a14 |   | G |
| B' |  =  | a20 a21 a22 a23 a24 | * | B |
| A' |     | a30 a31 a32 a33 a34 |   | A |
| 1  |     |  0   0   0   0   1  |   | 1 |</pre>
</object>-->

on the RGBA color and alpha values of every pixel on the input graphics to produce a result with a new set of RGBA color and alpha values.

The calculations are performed on non-premultiplied color values.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feColorMatrix>
    : <dfn>type</dfn> = "<span dfn-type=attr-value dfn-for=type><dfn>matrix</dfn> | <dfn>saturate</dfn> | <dfn>hueRotate</dfn> | <dfn>luminanceToAlpha</dfn></span>"
    ::
        Indicates the type of matrix operation. The keyword <a attr-value>matrix</a> indicates that a full 5x4 matrix of values will be provided. The other keywords represent convenience shortcuts to allow commonly used color operations to be performed without specifying a complete matrix.

        The <a for=svg>initial value</a> for <a element-attr for=feColorMatrix>type</a> is <a attr-value>matrix</a>.

        Animatable: yes.
    : <dfn>values</dfn> = "<em>list of <<number>>s</em>"
    ::
        The contents of <a element-attr for=feColorMatrix>values</a> depends on the value of attribute <a element-attr for=feColorMatrix>type</a>:
        * For <code>type="matrix"</code>, <a element-attr for=feColorMatrix>values</a> is a list of 20 matrix values (a00 a01 a02 a03 a04 a10 a11 ... a34), separated by whitespace and/or a comma. For example, the identity matrix could be expressed as:
            <pre>
type="matrix"
values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 1 0"</pre>
        * For <code>type="saturate"</code>, <a element-attr for=feColorMatrix>values</a> is a single real number value. A <a attr-value>saturate</a> operation is equivalent to the following matrix operation:
            <pre class=include>path: mathml/feColorMatrix01.mml</pre>
<!--<object data="mathml/feColorMatrix01.mml" type="application/mathml+xml" width="100%" height="130">
<pre>| R' |     | (0.2126 + 0.7873s)  (0.7152 - 0.7152s)  (0.0722 - 0.0722s) 0  0 |   | R |
| G' |     | (0.2126 - 0.2126s)  (0.7152 + 0.2848s)  (0.0722 - 0.0722s) 0  0 |   | G |
| B' |  =  | (0.2126 - 0.2126s)  (0.7152 - 0.7152s)  (0.0722 + 0.9278s) 0  0 | * | B |
| A' |     |           0                   0                   0        1  0 |   | A |
| 1  |     |           0                   0                   0        0  1 |   | 1 |</pre></object>-->

            Note: A value of ''0'' produces a fully desaturated (grayscale) filter result, while a value of ''1'' passes the filter input image through unchanged. Values outside the 0..1 range under- or oversaturates the filter input image respectively.

            Note: The precision of the luminance coefficients increased in comparison to previous specification texts [[Cmam]].
        * For <code>type="hueRotate"</code>, <a element-attr for=feColorMatrix>values</a> is a single one real number value (degrees). A <a attr-value>hueRotate</a> operation is equivalent to the following matrix operation:
            <pre class=include>path: mathml/feColorMatrix02.mml</pre>
<!--<object data="mathml/feColorMatrix02.mml" type="application/mathml+xml" width="100%" height="130">
<pre>| R' |     | a00  a01  a02  0  0 |   | R |
| G' |     | a10  a11  a12  0  0 |   | G |
| B' |  =  | a20  a21  a22  0  0 | * | B |
| A' |     | 0    0    0    1  0 |   | A |
| 1  |     | 0    0    0    0  1 |   | 1 |</pre>
</object>-->

            where the terms a00, a01, etc. are calculated as follows:

            <pre class=include>path: mathml/feColorMatrix03.mml</pre>
<!--<object data="mathml/feColorMatrix03.mml" type="application/mathml+xml" width="100%" height="230">
<pre>| a00 a01 a02 |     [0.2126 0.7152 0.0722]
| a10 a11 a12 | =   [0.2126 0.7152 0.0722] +
| a20 a21 a22 |     [0.2126 0.7152 0.0722]

                                          [ 0.7873 -0.7152 -0.0722]
                  cos(hueRotate value) *  [-0.2126  0.2848 -0.0722] +
                                          [-0.2126 -0.7152  0.9278]

                                          [-0.2126 -0.7152  0.9278]
                  sin(hueRotate value) *  [ 0.143   0.140  -0.283 ]
                                          [-0.7873  0.7152  0.0722]</pre>
  </object>-->
            Thus, the upper left term of the hue matrix turns out to be:

            <pre class=include>path: mathml/feColorMatrix04.mml</pre>
<!--<object data="mathml/feColorMatrix04.mml" type="application/mathml+xml" width="100%" height="30">
<pre>0.2127 + cos(hueRotate value) * 0.7873 - sin(hueRotate value) * 0.2127</pre>
</object>-->
        * For <code>type="luminanceToAlpha"</code>, <a element-attr for=feColorMatrix>values</a> is not applicable. A <a attr-value>luminanceToAlpha</a> operation is equivalent to the following matrix operation:

            <pre class=include>path: mathml/feColorMatrix05.mml</pre>
<!--<object data="mathml/feColorMatrix05.mml" type="application/mathml+xml" width="100%" height="130">
<pre>   | R' |     |      0        0        0  0  0 |   | R |
 | G' |     |      0        0        0  0  0 |   | G |
 | B' |  =  |      0        0        0  0  0 | * | B |
 | A' |     | 0.2126   0.7152   0.0722  0  0 |   | A |
 | 1  |     |      0        0        0  0  1 |   | 1 |</pre>
</object>-->

        The <a for=svg>initial value</a> for <a element-attr for=feColorMatrix>values</a>
        <dl class=switch>
            : if <code>type="matrix"</code>
            :: defaults to the identity matrix
            : if <code>type="saturate"</code>
            :: defaults to the value ''1''
            : if <code>type="hueRotate"</code>
            :: defaults to the value ''0'' which results in the identity matrix.
        </dl>

        If the number of entries in the <a element-attr for=feColorMatrix>values</a> list does not match the required number of entries by the <a element-attr for=feColorMatrix>type</a>, the filter primitive acts as a <a>pass through filter</a>.

        Animatable: yes.
</dl>

<div class=example>
    <pre><code highlight=svg>
        &lt;svg width="8cm" height="5cm" viewBox="0 0 800 500"
             xmlns="http://www.w3.org/2000/svg"&gt;
          &lt;title&gt;Example feColorMatrix - Examples of feColorMatrix operations&lt;/title&gt;
          &lt;desc&gt;Five text strings showing the effects of feColorMatrix:
                an unfiltered text string acting as a reference,
                use of the feColorMatrix matrix option to convert to grayscale,
                use of the feColorMatrix saturate option,
                use of the feColorMatrix hueRotate option,
                and use of the feColorMatrix luminanceToAlpha option.&lt;/desc&gt;
          &lt;defs&gt;
            &lt;linearGradient id="MyGradient" gradientUnits="userSpaceOnUse"
                    x1="100" y1="0" x2="500" y2="0"&gt;
              &lt;stop offset="0" stop-color="#ff00ff" /&gt;
              &lt;stop offset=".33" stop-color="#88ff88" /&gt;
              &lt;stop offset=".67" stop-color="#2020ff" /&gt;
              &lt;stop offset="1" stop-color="#d00000" /&gt;
            &lt;/linearGradient&gt;
            &lt;filter id="Matrix" filterUnits="objectBoundingBox"
                    x="0%" y="0%" width="100%" height="100%"&gt;
              &lt;feColorMatrix type="matrix" in="SourceGraphic"
                   values=".33 .33 .33 0 0
                           .33 .33 .33 0 0
                           .33 .33 .33 0 0
                           .33 .33 .33 0 0"/&gt;
            &lt;/filter&gt;
            &lt;filter id="Saturate40" filterUnits="objectBoundingBox"
                    x="0%" y="0%" width="100%" height="100%"&gt;
              &lt;feColorMatrix type="saturate" in="SourceGraphic" values="0.4"/&gt;
            &lt;/filter&gt;
            &lt;filter id="HueRotate90" filterUnits="objectBoundingBox"
                    x="0%" y="0%" width="100%" height="100%"&gt;
              &lt;feColorMatrix type="hueRotate" in="SourceGraphic" values="90"/&gt;
            &lt;/filter&gt;
            &lt;filter id="LuminanceToAlpha" filterUnits="objectBoundingBox"
                    x="0%" y="0%" width="100%" height="100%"&gt;
              &lt;feColorMatrix type="luminanceToAlpha" in="SourceGraphic" result="a"/&gt;
              &lt;feComposite in="SourceGraphic" in2="a" operator="in" /&gt;
            &lt;/filter&gt;
          &lt;/defs&gt;
          &lt;rect fill="none" stroke="blue"
                x="1" y="1" width="798" height="498"/&gt;
          &lt;g font-family="Verdana" font-size="75"
                    font-weight="bold" fill="url(#MyGradient)" &gt;
            &lt;rect x="100" y="0" width="500" height="20" /&gt;
            &lt;text x="100" y="90"&gt;Unfiltered&lt;/text&gt;
            &lt;text x="100" y="190" filter="url(#Matrix)" &gt;Matrix&lt;/text&gt;
            &lt;text x="100" y="290" filter="url(#Saturate40)" &gt;Saturate&lt;/text&gt;
            &lt;text x="100" y="390" filter="url(#HueRotate90)" &gt;HueRotate&lt;/text&gt;
            &lt;text x="100" y="490" filter="url(#LuminanceToAlpha)" &gt;Luminance&lt;/text&gt;
          &lt;/g&gt;
        &lt;/svg&gt;
    </code></pre>

    <div class=figure>
        <img alt="Example " src="examples/feColorMatrix.png">
        <p class=caption>Example of feColorMatrix</p>
    </div>

    <a href="examples/feColorMatrix.svg">View this example as SVG</a>
</div>

## Filter primitive <a element>feComponentTransfer</a> ## {#feComponentTransferElement}

<pre class=include>
path: templates/effect-in1.md
macros:
    name: feComponentTransfer
    model: <a element>feFuncR</a>, <a element>feFuncG</a>, <a element>feFuncB</a>, <a element>feFuncA</a>, <a element>script</a>
    interface: SVGFEComponentTransferElement
</pre>

This filter primitive performs component-wise remapping of data as follows:

<pre>R' = <a element>feFuncR</a>( R )
G' = <a element>feFuncG</a>( G )
B' = <a element>feFuncB</a>( B )
A' = <a element>feFuncA</a>( A )</pre>

for every pixel. It allows operations like brightness adjustment, contrast adjustment, color balance or thresholding.

The calculations are performed on non-premultiplied color values.

The child elements of a <a element>feComponentTransfer</a> element specify the transfer functions for the four channels:

* <a element>feFuncR</a> - transfer function for the red component of the input graphic
* <a element>feFuncG</a> - transfer function for the green component of the input graphic
* <a element>feFuncB</a> - transfer function for the blue component of the input graphic
* <a element>feFuncA</a> - transfer function for the alpha component of the input graphic

The set of <a element>feFuncR</a>, <a element>feFuncG</a>, <a element>feFuncB</a>, <a element>feFuncA</a> elements are also called <dfn id="transfer-function-element">transfer function element</dfn>s.

The following rules apply to the processing of the <a element>feComponentTransfer</a> element:

* If more than one <a>transfer function element</a> of the same kind is specified, the last occurrence is to be used.
* If any of the <a>transfer function elements</a> are unspecified, the <a element>feComponentTransfer</a> must be processed as if those <a>transfer function elements</a> were specified with their <a element-attr for=feComponentTransfer>type</a> attributes set to ''identity''.


### Transfer function <a element>feFuncR</a> ### {#feFuncRElement}

<pre class=include>
path: templates/effect-source.md
macros:
    name: feFuncR
    interface: SVGFEFuncRElement
    catagories: <a>transfer function element</a>
    attributes: <li><a href='#transfer-function-element-attributes'>transfer function element attributes</a><span class=expanding> — <a element-attr for=feComponentTransfer>type</a>, <a element-attr for=feComponentTransfer>tableValues</a>, <a element-attr for=feComponentTransfer>slope</a>, <a element-attr for=feComponentTransfer>intercept</a>, <a element-attr for=feComponentTransfer>amplitude</a>, <a element-attr for=feComponentTransfer>exponent</a>, <a element-attr for=feComponentTransfer>offset</a></span></li>
</pre>

The attributes below are the <dfn id="transfer-function-element-attributes">transfer function element attributes</dfn>, which apply to the <a>transfer function elements</a>.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feComponentTransfer>
    : <dfn>type</dfn> = "<a attr-value>identity</a> | <a attr-value>table</a> | <a attr-value>discrete</a> | <a attr-value>linear</a> | <a attr-value>gamma</a>"
    ::
        Indicates the type of component transfer function. The type of function determines the applicability of the other attributes.

        In the following, C is the initial component (e.g., <a element>feFuncR</a>), C' is the remapped component; both in the closed interval [0,1].
        * For <dfn attr-value for=type>identity</dfn>:
            <pre>C' = C</pre>
        * For <dfn attr-value for=type>table</dfn>, the function is defined by linear interpolation between values given in the attribute <a element-attr>tableValues</a>. The table has <em>n+1</em> values (i.e., v<sub>0</sub> to v<sub>n</sub>) specifying the start and end values for <em>n</em> evenly sized interpolation regions. Interpolations use the following formula:

            For a value <code>C &lt; 1</code> find <code>k</code> such that:

            <code>k/n &lt;= C &lt; (k+1)/n</code>

            The result <code>C'</code> is given by:

            <code>C' = v<sub>k</sub> + (C - k/n)*n * (v<sub>k+1</sub> - v<sub>k</sub>)</code>

            If <code>C = 1</code> then:

            <code>C' = v<sub>n</sub>.</code>
        * For <dfn attr-value for=type>discrete</dfn>, the function is defined by the step function given in the attribute <a element-attr>tableValues</a>, which provides a list of <em>n</em> values (i.e., v<sub>0</sub> to v<sub>n-1</sub>) in order to identify a step function consisting of <em>n</em> steps. The step function is defined by the following formula:

            For a value <code>C &lt; 1</code> find <code>k</code> such that:

            <code>k/n &lt;= C &lt; (k+1)/n</code>

            The result <code>C'</code> is given by:

            <code>C' = v<sub>k</sub></code>

            If <code>C = 1</code> then:

            <code>C' = v<sub>n-1</sub>.</code>
        * For <dfn attr-value for=type>linear</dfn>, the function is defined by the following linear equation:

            <code>C' = <a element-attr>slope</a> * C + <a element-attr>intercept</a></code>
        * For <dfn attr-value for=type>gamma</dfn>, the function is defined by the following exponential function:

            <code>C' = <a element-attr for=feComponentTransfer>amplitude</a> * pow(C, <a element-attr=feComponentTransfer>exponent</a>) + <a element-attr for=feComponentTransfer>offset</a></code>

        The <a for=svg>initial value</a> for <a element-attr for=feComponentTransfer>type</a> is <a attr-value>identity</a>.

        Animatable: yes.
    : <dfn>tableValues</dfn> = "<em>(list of <<number>>s)</em>"
    ::
        When <code>type="table"</code>, the list of <<number>> s <em>v0,v1,...vn</em>, separated by white space and/or a comma, which define the lookup table. An empty list results in an identity transfer function.

        If the attribute is not specified, then the effect is as if an empty list were provided.

        Animatable: yes.
    : <dfn>slope</dfn> = "<em><<number>></em>"
    ::
        When <code>type="linear"</code>, the slope of the linear function.

        The <a for=svg>initial value</a> for <a element-attr>slope</a> is ''1''.

        Animatable: yes.
    : <dfn>intercept</dfn> = "<em><<number>></em>"
    ::
        When <code>type="linear"</code>, the intercept of the linear function.

        The <a for=svg>initial value</a> for <a element-attr>intercept</a> is ''0''.

        Animatable: yes.
    : <dfn>amplitude</dfn> = "<em><<number>></em>"
    ::
        When <code>type="gamma"</code>, the amplitude of the gamma function.

        The <a for=svg>initial value</a> for <a element-attr>amplitude</a> is ''1''.

        Animatable: yes.
    : <dfn>exponent</dfn> = "<em><<number>></em>"
    ::
        When <code>type="gamma"</code>, the exponent of the gamma function.

        The <a for=svg>initial value</a> for <a element-attr>exponent</a> is ''1''.

        Animatable: yes.
    : <dfn>offset</dfn> = "<em><<number>></em>"
    ::
        When <code>type="gamma"</code>, the offset of the gamma function.

        The <a for=svg>initial value</a> for <a element-attr for=feComponentTransfer>offset</a> is ''0''.

        Animatable: yes.
</dl>

<div class=example>
    <pre><code highlight=svg>
        &lt;svg width="8cm" height="4cm" viewBox="0 0 800 400"
             xmlns="http://www.w3.org/2000/svg"&gt;
          &lt;title&gt;Example feComponentTransfer - Examples of feComponentTransfer operations&lt;/title&gt;
          &lt;desc&gt;Four text strings showing the effects of feComponentTransfer:
                an identity function acting as a reference,
                use of the feComponentTransfer table option,
                use of the feComponentTransfer linear option,
                and use of the feComponentTransfer gamma option.&lt;/desc&gt;
          &lt;defs&gt;
            &lt;linearGradient id="MyGradient" gradientUnits="userSpaceOnUse"
                    x1="100" y1="0" x2="600" y2="0"&gt;
              &lt;stop offset="0" stop-color="#ff0000" /&gt;
              &lt;stop offset=".33" stop-color="#00ff00" /&gt;
              &lt;stop offset=".67" stop-color="#0000ff" /&gt;
              &lt;stop offset="1" stop-color="#000000" /&gt;
            &lt;/linearGradient&gt;
            &lt;filter id="Identity" filterUnits="objectBoundingBox"
                    x="0%" y="0%" width="100%" height="100%"&gt;
              &lt;feComponentTransfer&gt;
                &lt;feFuncR type="identity"/&gt;
                &lt;feFuncG type="identity"/&gt;
                &lt;feFuncB type="identity"/&gt;
                &lt;feFuncA type="identity"/&gt;
              &lt;/feComponentTransfer&gt;
            &lt;/filter&gt;
            &lt;filter id="Table" filterUnits="objectBoundingBox"
                    x="0%" y="0%" width="100%" height="100%"&gt;
              &lt;feComponentTransfer&gt;
                &lt;feFuncR type="table" tableValues="0 0 1 1"/&gt;
                &lt;feFuncG type="table" tableValues="1 1 0 0"/&gt;
                &lt;feFuncB type="table" tableValues="0 1 1 0"/&gt;
              &lt;/feComponentTransfer&gt;
            &lt;/filter&gt;
            &lt;filter id="Linear" filterUnits="objectBoundingBox"
                    x="0%" y="0%" width="100%" height="100%"&gt;
              &lt;feComponentTransfer&gt;
                &lt;feFuncR type="linear" slope=".5" intercept=".25"/&gt;
                &lt;feFuncG type="linear" slope=".5" intercept="0"/&gt;
                &lt;feFuncB type="linear" slope=".5" intercept=".5"/&gt;
              &lt;/feComponentTransfer&gt;
            &lt;/filter&gt;
            &lt;filter id="Gamma" filterUnits="objectBoundingBox"
                    x="0%" y="0%" width="100%" height="100%"&gt;
              &lt;feComponentTransfer&gt;
                &lt;feFuncR type="gamma" amplitude="2" exponent="5" offset="0"/&gt;
                &lt;feFuncG type="gamma" amplitude="2" exponent="3" offset="0"/&gt;
                &lt;feFuncB type="gamma" amplitude="2" exponent="1" offset="0"/&gt;
              &lt;/feComponentTransfer&gt;
            &lt;/filter&gt;
          &lt;/defs&gt;
          &lt;rect fill="none" stroke="blue"
                x="1" y="1" width="798" height="398"/&gt;
          &lt;g font-family="Verdana" font-size="75"
                    font-weight="bold" fill="url(#MyGradient)" &gt;
            &lt;rect x="100" y="0" width="600" height="20" /&gt;
            &lt;text x="100" y="90"&gt;Identity&lt;/text&gt;
            &lt;text x="100" y="190" filter="url(#Table)" &gt;TableLookup&lt;/text&gt;
            &lt;text x="100" y="290" filter="url(#Linear)" &gt;LinearFunc&lt;/text&gt;
            &lt;text x="100" y="390" filter="url(#Gamma)" &gt;GammaFunc&lt;/text&gt;
          &lt;/g&gt;
        &lt;/svg&gt;
    </code></pre>

    <div class=figure>
        <img alt="Example for feComponentTransfer" src="examples/feComponentTransfer.png">
        <p class=caption>Example for feComponentTransfer</p>
    </div>

    <a href="examples/feComponentTransfer.svg">View this example as SVG</a>
</div>


### Transfer function <a element>feFuncG</a> ### {#feFuncGElement}

<pre class=include>
path: templates/effect-source.md
macros:
    name: feFuncG
    interface: SVGFEFuncGElement
    catagories: <a>transfer function element</a>
    attributes: <li><a href='#transfer-function-element-attributes'>transfer function element attributes</a><span class=expanding> — <a element-attr for=feComponentTransfer>type</a>, <a element-attr for=feComponentTransfer>tableValues</a>, <a element-attr for=feComponentTransfer>slope</a>, <a element-attr for=feComponentTransfer>intercept</a>, <a element-attr for=feComponentTransfer>amplitude</a>, <a element-attr for=feComponentTransfer>exponent</a>, <a element-attr for=feComponentTransfer>offset</a></span></li>
</pre>

See <a element>feFuncR</a> for the definitions of the attribute values.

### Transfer function <a element>feFuncB</a> ### {#feFuncBElement}

<pre class=include>
path: templates/effect-source.md
macros:
    name: feFuncB
    interface: SVGFEFuncBElement
    catagories: <a>transfer function element</a>
    attributes: <li><a href='#transfer-function-element-attributes'>transfer function element attributes</a><span class=expanding> — <a element-attr for=feComponentTransfer>type</a>, <a element-attr for=feComponentTransfer>tableValues</a>, <a element-attr for=feComponentTransfer>slope</a>, <a element-attr for=feComponentTransfer>intercept</a>, <a element-attr for=feComponentTransfer>amplitude</a>, <a element-attr for=feComponentTransfer>exponent</a>, <a element-attr for=feComponentTransfer>offset</a></span></li>
</pre>

See <a element>feFuncR</a> for the definitions of the attribute values.


### Transfer function <a element>feFuncA</a> ### {#feFuncAElement}

<pre class=include>
path: templates/effect-source.md
macros:
    name: feFuncA
    interface: SVGFEFuncAElement
    catagories: <a>transfer function element</a>
    attributes: <li><a href='#transfer-function-element-attributes'>transfer function element attributes</a><span class=expanding> — <a element-attr for=feComponentTransfer>type</a>, <a element-attr for=feComponentTransfer>tableValues</a>, <a element-attr for=feComponentTransfer>slope</a>, <a element-attr for=feComponentTransfer>intercept</a>, <a element-attr for=feComponentTransfer>amplitude</a>, <a element-attr for=feComponentTransfer>exponent</a>, <a element-attr for=feComponentTransfer>offset</a></span></li>
</pre>

See <a element>feFuncR</a> for the definitions of the attribute values.


## Filter primitive <a element>feComposite</a> ## {#feCompositeElement}

<pre class=include>
path: templates/effect-in2.md
macros:
    name: feComposite
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFECompositeElement
    attributes: <li><a element-attr for=feComposite>operator</a></li><li><a element-attr for=feComposite>k1</a></li><li><a element-attr for=feComposite>k2</a></li><li><a element-attr for=feComposite>k3</a></li><li><a element-attr for=feComposite>k4</a></li>
</pre>

This filter performs the combination of the two input images pixel-wise in image space using one of the Porter-Duff [[PORTERDUFF]] compositing operations: <a attr-value>over</a>, ''in'', ''atop'', ''out'', ''xor'', ''lighter'' [[!COMPOSITING-1]]. Additionally, a component-wise <em>arithmetic</em> operation (with the result clamped between [0..1]) can be applied.

The <em>arithmetic</em> operation is useful for combining the output from the <a element>feDiffuseLighting</a> and <a element>feSpecularLighting</a> filters with texture data. It is also useful for implementing <em>dissolve</em>. If the <em>arithmetic</em> operation is chosen, each result pixel is computed using the following formula:

<pre>
result = k1*i1*i2 + k2*i1 + k3*i2 + k4
</pre>

where:

* <code>i1</code> and <code>i2</code> indicate the corresponding pixel channel values of the input image, which map to <a element-attr>in</a> and <a element-attr for=feComposite>in2</a> respectively
* <code>k1, k2, k3</code> and <code>k4</code> indicate the values of the attributes with the same name

For this filter primitive, the extent of the resulting image might grow as described in the section that describes the <a>filter primitive subregion</a>.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feComposite>
    : <dfn>operator</dfn> = "<span dfn-type=attr-value dfn-for=feComposite/operator><dfn>over</dfn> | <dfn>in</dfn> | <dfn>out</dfn> | <dfn>atop</dfn> | <dfn>xor</dfn> | <dfn>lighter</dfn> | <dfn>arithmetic</dfn></span>"
    ::
        The compositing operation that is to be performed. All of the <a element-attr for=feComposite>operator</a> types except ''arithmetic'' match the corresponding operation as described in [[!COMPOSITING-1]] with <a element-attr>in</a> representing the source and <a element-attr for=feComposite>in2</a> representing the destination. The ''arithmetic'' operator is described above.

        The <a for=svg>initial value</a> for <a element-attr for=feComposite>operator</a> is <a attr-value>over</a>.

        Animatable: yes.
    : <dfn>k1</dfn> = "<<number>>"
    ::
        Only applicable if <code>operator="arithmetic"</code>.

        The <a for=svg>initial value</a> for <a element-attr>k1</a> is ''0''.

        Animatable: yes.
    : <dfn>k2</dfn> = "<em><<number>></em>"
    ::
        Only applicable if <code>operator="arithmetic"</code>.

        The <a for=svg>initial value</a> for <a element-attr>k2</a> is ''0''.

        Animatable: yes.
    : <dfn>k3</dfn> = "<<number>>"
    ::
        Only applicable if <code>operator="arithmetic"</code>.

        The <a for=svg>initial value</a> for <a element-attr>k3</a> is ''0''.

        Animatable: yes.
    : <dfn>k4</dfn> = "<<number>>"
    ::
        Only applicable if <code>operator="arithmetic"</code>.

        The <a for=svg>initial value</a> for <a element-attr>k4</a> is ''0''.

        Animatable: yes.
    : <dfn>in2</dfn> = "<em>(see <a element-attr>in</a> attribute)</em>"
    ::
        The second input image to the compositing operation.

        Animatable: yes.
</dl>

Note: Compositing and Blending [[!COMPOSITING-1]] defines more compositing keywords. The functionality of the additional keywords can be archived by switching the input filter primitives <a element-attr>in</a> and <a element-attr for=feComposite>in2</a>.

<div class=example>
    <pre><code highlight=svg>
        &lt;svg width="330" height="195" viewBox="0 0 1100 650"
             xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"&gt;
          &lt;title&gt;Example feComposite - Examples of feComposite operations&lt;/title&gt;
          &lt;desc&gt;Four rows of six pairs of overlapping triangles depicting
                the six different feComposite operators under different
                opacity values and different clearing of the background.&lt;/desc&gt;
          &lt;defs&gt;
            &lt;desc&gt;Define two sets of six filters for each of the six compositing operators.
                  The first set wipes out the background image by flooding with opaque white.
                  The second set does not wipe out the background, with the result
                  that the background sometimes shines through and is other cases
                  is blended into itself (i.e., "double-counting").&lt;/desc&gt;
            &lt;filter id="overFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feFlood flood-color="#ffffff" flood-opacity="1" result="flood"/&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" operator="over" result="comp"/&gt;
              &lt;feMerge&gt; &lt;feMergeNode in="flood"/&gt; &lt;feMergeNode in="comp"/&gt; &lt;/feMerge&gt;
            &lt;/filter&gt;
            &lt;filter id="inFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feFlood flood-color="#ffffff" flood-opacity="1" result="flood"/&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" operator="in" result="comp"/&gt;
              &lt;feMerge&gt; &lt;feMergeNode in="flood"/&gt; &lt;feMergeNode in="comp"/&gt; &lt;/feMerge&gt;
            &lt;/filter&gt;
            &lt;filter id="outFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feFlood flood-color="#ffffff" flood-opacity="1" result="flood"/&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" operator="out" result="comp"/&gt;
              &lt;feMerge&gt; &lt;feMergeNode in="flood"/&gt; &lt;feMergeNode in="comp"/&gt; &lt;/feMerge&gt;
            &lt;/filter&gt;
            &lt;filter id="atopFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feFlood flood-color="#ffffff" flood-opacity="1" result="flood"/&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" operator="atop" result="comp"/&gt;
              &lt;feMerge&gt; &lt;feMergeNode in="flood"/&gt; &lt;feMergeNode in="comp"/&gt; &lt;/feMerge&gt;
            &lt;/filter&gt;
            &lt;filter id="xorFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feFlood flood-color="#ffffff" flood-opacity="1" result="flood"/&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" operator="xor" result="comp"/&gt;
              &lt;feMerge&gt; &lt;feMergeNode in="flood"/&gt; &lt;feMergeNode in="comp"/&gt; &lt;/feMerge&gt;
            &lt;/filter&gt;
            &lt;filter id="arithmeticFlood" filterUnits="objectBoundingBox"
                    x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feFlood flood-color="#ffffff" flood-opacity="1" result="flood"/&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" result="comp"
                           operator="arithmetic" k1=".5" k2=".5" k3=".5" k4=".5"/&gt;
              &lt;feMerge&gt; &lt;feMergeNode in="flood"/&gt; &lt;feMergeNode in="comp"/&gt; &lt;/feMerge&gt;
            &lt;/filter&gt;
            &lt;filter id="overNoFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" operator="over" result="comp"/&gt;
            &lt;/filter&gt;
            &lt;filter id="inNoFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" operator="in" result="comp"/&gt;
            &lt;/filter&gt;
            &lt;filter id="outNoFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" operator="out" result="comp"/&gt;
            &lt;/filter&gt;
            &lt;filter id="atopNoFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" operator="atop" result="comp"/&gt;
            &lt;/filter&gt;
            &lt;filter id="xorNoFlood" filterUnits="objectBoundingBox" x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" operator="xor" result="comp"/&gt;
            &lt;/filter&gt;
            &lt;filter id="arithmeticNoFlood" filterUnits="objectBoundingBox"
                    x="-5%" y="-5%" width="110%" height="110%"&gt;
              &lt;feComposite in="SourceGraphic" in2="BackgroundImage" result="comp"
                           operator="arithmetic" k1=".5" k2=".5" k3=".5" k4=".5"/&gt;
            &lt;/filter&gt;
            &lt;path id="Blue100" d="M 0 0 L 100 0 L 100 100 z" fill="#00ffff" /&gt;
            &lt;path id="Red100" d="M 0 0 L 0 100 L 100 0 z" fill="#ff00ff" /&gt;
            &lt;path id="Blue50" d="M 0 125 L 100 125 L 100 225 z" fill="#00ffff" fill-opacity=".5" /&gt;
            &lt;path id="Red50" d="M 0 125 L 0 225 L 100 125 z" fill="#ff00ff" fill-opacity=".5" /&gt;
            &lt;g id="TwoBlueTriangles"&gt;
              &lt;use xlink:href="#Blue100"/&gt;
              &lt;use xlink:href="#Blue50"/&gt;
            &lt;/g&gt;
            &lt;g id="BlueTriangles"&gt;
              &lt;use transform="translate(275,25)" xlink:href="#TwoBlueTriangles"/&gt;
              &lt;use transform="translate(400,25)" xlink:href="#TwoBlueTriangles"/&gt;
              &lt;use transform="translate(525,25)" xlink:href="#TwoBlueTriangles"/&gt;
              &lt;use transform="translate(650,25)" xlink:href="#TwoBlueTriangles"/&gt;
              &lt;use transform="translate(775,25)" xlink:href="#TwoBlueTriangles"/&gt;
              &lt;use transform="translate(900,25)" xlink:href="#TwoBlueTriangles"/&gt;
            &lt;/g&gt;
          &lt;/defs&gt;

          &lt;rect fill="none" stroke="blue" x="1" y="1" width="1098" height="648"/&gt;
          &lt;g font-family="Verdana" font-size="40" shape-rendering="crispEdges"&gt;
            &lt;desc&gt;Render the examples using the filters that draw on top of
                  an opaque white surface, thus obliterating the background.&lt;/desc&gt;
            &lt;g isolation="isolate"&gt;
              &lt;text x="15" y="75"&gt;opacity 1.0&lt;/text&gt;
              &lt;text x="15" y="115" font-size="27"&gt;(with feFlood)&lt;/text&gt;
              &lt;text x="15" y="200"&gt;opacity 0.5&lt;/text&gt;
              &lt;text x="15" y="240" font-size="27"&gt;(with feFlood)&lt;/text&gt;
              &lt;use xlink:href="#BlueTriangles"/&gt;
              &lt;g transform="translate(275,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#overFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#overFlood)" /&gt;
                &lt;text x="5" y="275"&gt;over&lt;/text&gt;
              &lt;/g&gt;
              &lt;g transform="translate(400,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#inFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#inFlood)" /&gt;
                &lt;text x="35" y="275"&gt;in&lt;/text&gt;
              &lt;/g&gt;
              &lt;g transform="translate(525,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#outFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#outFlood)" /&gt;
                &lt;text x="15" y="275"&gt;out&lt;/text&gt;
              &lt;/g&gt;
              &lt;g transform="translate(650,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#atopFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#atopFlood)" /&gt;
                &lt;text x="10" y="275"&gt;atop&lt;/text&gt;
              &lt;/g&gt;
              &lt;g transform="translate(775,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#xorFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#xorFlood)" /&gt;
                &lt;text x="15" y="275"&gt;xor&lt;/text&gt;
              &lt;/g&gt;
              &lt;g transform="translate(900,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#arithmeticFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#arithmeticFlood)" /&gt;
                &lt;text x="-25" y="275"&gt;arithmetic&lt;/text&gt;
              &lt;/g&gt;
            &lt;/g&gt;
            &lt;g transform="translate(0,325)" isolation="isolate"&gt;
            &lt;desc&gt;Render the examples using the filters that do not obliterate
                  the background, thus sometimes causing the background to continue
                  to appear in some cases, and in other cases the background
                  image blends into itself ("double-counting").&lt;/desc&gt;
              &lt;text x="15" y="75"&gt;opacity 1.0&lt;/text&gt;
              &lt;text x="15" y="115" font-size="27"&gt;(without feFlood)&lt;/text&gt;
              &lt;text x="15" y="200"&gt;opacity 0.5&lt;/text&gt;
              &lt;text x="15" y="240" font-size="27"&gt;(without feFlood)&lt;/text&gt;
              &lt;use xlink:href="#BlueTriangles"/&gt;
              &lt;g transform="translate(275,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#overNoFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#overNoFlood)" /&gt;
                &lt;text x="5" y="275"&gt;over&lt;/text&gt;
              &lt;/g&gt;
              &lt;g transform="translate(400,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#inNoFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#inNoFlood)" /&gt;
                &lt;text x="35" y="275"&gt;in&lt;/text&gt;
              &lt;/g&gt;
              &lt;g transform="translate(525,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#outNoFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#outNoFlood)" /&gt;
                &lt;text x="15" y="275"&gt;out&lt;/text&gt;
              &lt;/g&gt;
              &lt;g transform="translate(650,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#atopNoFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#atopNoFlood)" /&gt;
                &lt;text x="10" y="275"&gt;atop&lt;/text&gt;
              &lt;/g&gt;
              &lt;g transform="translate(775,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#xorNoFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#xorNoFlood)" /&gt;
                &lt;text x="15" y="275"&gt;xor&lt;/text&gt;
              &lt;/g&gt;
              &lt;g transform="translate(900,25)"&gt;
                &lt;use xlink:href="#Red100" filter="url(#arithmeticNoFlood)" /&gt;
                &lt;use xlink:href="#Red50" filter="url(#arithmeticNoFlood)" /&gt;
                &lt;text x="-25" y="275"&gt;arithmetic&lt;/text&gt;
              &lt;/g&gt;
            &lt;/g&gt;
          &lt;/g&gt;
        &lt;/svg&gt;
    </code></pre>

    <div class=figure>
        <img alt="Example of feComposite" src="examples/feComposite.png">
        <p class=caption>Example of feComposite</p>
    </div>

    <a href="examples/feComposite.svg">View this example as SVG</a>
</div>


## Filter primitive <a element>feConvolveMatrix</a> ## {#feConvolveMatrixElement}

<pre class=include>
path: templates/effect-in1.md
macros:
    name: feConvolveMatrix
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFEConvolveMatrixElement
    attributes: <li><a element-attr for=feConvolveMatrix>order</a></li><li><a element-attr for=feConvolveMatrix>kernelMatrix</a></li><li><a element-attr for=feConvolveMatrix>divisor</a></li><li><a element-attr for=feConvolveMatrix>bias</a></li><li><a element-attr for=feConvolveMatrix>targetX</a></li><li><a element-attr for=feConvolveMatrix>targetY</a></li><li><a element-attr for=feConvolveMatrix>edgeMode</a></li><li><a element-attr for=feConvolveMatrix>kernelUnitLength</a></li><li><a element-attr for=feConvolveMatrix>preserveAlpha</a></li>
</pre>

feConvolveMatrix applies a matrix convolution filter effect. A convolution combines pixels in the input image with neighboring pixels to produce a resulting image. A wide variety of imaging operations can be achieved through convolutions, including blurring, edge detection, sharpening, embossing and beveling.

A matrix convolution is based on an n-by-m matrix (the convolution kernel) which describes how a given pixel value in the input image is combined with its neighboring pixel values to produce a resulting pixel value. Each result pixel is determined by applying the kernel matrix to the corresponding source pixel and its neighboring pixels. The basic convolution formula which is applied to each color value for a given pixel is:

<div id="feConvolveMatrixElementFormula">
    <pre class=include>path: mathml/feConvolveMatrix00.mml</pre>
</div>

where "orderX" and "orderY" represent the X and Y values for the <a element-attr>order</a> attribute, "targetX" represents the value of the <a element-attr>targetX</a> attribute, "targetY" represents the value of the <a element-attr>targetY</a> attribute, "kernelMatrix" represents the value of the <a element-attr>kernelMatrix</a> attribute, "divisor" represents the value of the <a element-attr>divisor</a> attribute, and "bias" represents the value of the <a element-attr>bias</a> attribute.

In the above formulas the values in the kernel matrix are applied such that the kernel matrix is rotated 180 degrees relative to the source and destination images in order to match convolution theory as described in many computer graphics textbooks.

To illustrate, suppose you have a input image which is 5 pixels by 5 pixels, whose color values for one of the color channels are as follows:

<pre class=include>path: mathml/feConvolveMatrix01.mml</pre>

and you define a 3-by-3 convolution kernel as follows:

<pre class=include>path: mathml/feConvolveMatrix02.mml</pre>

Let's focus on the color value at the second row and second column of the image (source pixel value is 120). Assuming the simplest case (where the input image's pixel grid aligns perfectly with the kernel's pixel grid) and assuming default values for attributes <a element-attr>divisor</a>, <a element-attr>targetX</a> and <a element-attr>targetY</a>, then resulting color value will be:

<pre class=include>path: mathml/feConvolveMatrix03.mml</pre>

Because they operate on pixels, matrix convolutions are inherently resolution-dependent. To make <a element>feConvolveMatrix</a> produce resolution-independent results, an explicit value should be provided for the attribute <a element-attr for=feConvolveMatrix>kernelUnitLength</a>.

<a element-attr for=feConvolveMatrix>kernelUnitLength</a>, in combination with the other attributes, defines an implicit pixel grid in the filter effects coordinate system (i.e., the coordinate system established by the <a element-attr>primitiveUnits</a> attribute). The input image will be temporarily rescaled to match its pixels with <a element-attr for=feConvolveMatrix>kernelUnitLength</a>. The convolution happens on the resampled image. After applying the convolution, the image is resampled back to the original resolution.

When the image must be resampled to match the coordinate system defined by <a element-attr for=feConvolveMatrix>kernelUnitLength</a> prior to convolution, or resampled to match the device coordinate system after convolution, it is recommended that high quality viewers make use of appropriate interpolation techniques, for example bilinear or bicubic. Depending on the speed of the available interpolents, this choice may be affected by the 'image-rendering' property setting. Note that implementations might choose approaches that minimize or eliminate resampling when not necessary to produce proper results, such as when the document is zoomed out such that <a element-attr for=feConvolveMatrix>kernelUnitLength</a> is considerably smaller than a device pixel.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feConvolveMatrix>
    : <dfn id="element-attrdef-order">order</dfn> = "<em><<number-optional-number>></em>"
    ::
        Indicates the number of cells in each dimension for <a element-attr>kernelMatrix</a>. The values provided must be <<integer>> s greater than zero. Values that are not integers will be truncated, i.e. rounded to the closest integer value towards zero. The first number, &lt;orderX&gt;, indicates the number of columns in the matrix. The second number, &lt;orderY&gt;, indicates the number of rows in the matrix. If &lt;orderY&gt; is not provided, it defaults to &lt;orderX&gt;.

        It is recommended that only small values (e.g., ''3'') be used; higher values may result in very high CPU overhead and usually do not produce results that justify the impact on performance.

        The <a for=svg>initial value</a> for <a element-attr>order</a> is ''3''.

        Animatable: yes.
    : <dfn>kernelMatrix</dfn> = "<em>&lt;list of numbers&gt;</em>"
    ::
        The list of <<number>> s that make up the kernel matrix for the convolution. Values are separated by space characters and/or a comma. The number of entries in the list must equal &lt;orderX&gt; times &lt;orderY&gt;.

        If the result of <code>orderX * orderY</code> is not equal to the the number of entries in the value list, the filter primitive acts as a <a>pass through filter</a>.

        Issue(237): How to behave on invalid number of entries in the value list?

        Animatable: yes.
    : <dfn>divisor</dfn> = "<em><<number>></em>"
    ::
        After applying the <a element-attr>kernelMatrix</a> to the input image to yield a number, that number is divided by <a element-attr>divisor</a> to yield the final destination color value. A divisor that is the sum of all the matrix values tends to have an evening effect on the overall color intensity of the result. If the specified divisor is ''0'' then the default value will be used instead.

        The <a for=svg>initial value</a> is the sum of all values in <a element-attr>kernelMatrix</a>, with the exception that if the sum is zero, then the divisor is set to ''1''.

        Animatable: yes.
    : <dfn>bias</dfn> = "<em><<number>></em>"
    ::
        After applying the <a element-attr>kernelMatrix</a> to the input image to yield a number and applying the <a element-attr>divisor</a>, the <a element-attr>bias</a> attribute is added to each component. One application of <a element-attr>bias</a> is when it is desirable to have ''.5'' gray value be the zero response of the filter. The bias property shifts the range of the filter. This allows representation of values that would otherwise be clamped to 0 or 1.

        The <a for=svg>initial value</a> for <a element-attr>bias</a> is ''0''.

        Animatable: yes.
    : <dfn>targetX</dfn> = "<<integer>>"
    ::
        Determines the positioning in X of the convolution matrix relative to a given target pixel in the input image. The leftmost column of the matrix is column number zero. The value must be such that: 0 &lt;= targetX &lt; orderX. By default, the convolution matrix is centered in X over each pixel of the input image (i.e., targetX = floor ( orderX / 2 )).

        Animatable: yes.
    : <dfn>targetY</dfn> = "<<integer>>"
    ::
        Determines the positioning in Y of the convolution matrix relative to a given target pixel in the input image. The topmost row of the matrix is row number zero. The value must be such that: 0 &lt;= targetY &lt; orderY. By default, the convolution matrix is centered in Y over each pixel of the input image (i.e., targetY = floor ( orderY / 2 )).

        Animatable: yes.
    : <dfn>edgeMode</dfn> = "<span dfn-type=attr-value dfn-for=feConvolveMatrix/operator><a attr-value>duplicate</a> | <a attr-value>wrap</a> | <a attr-value>mirror</a> | none</span>"
    ::
        Determines how to extend the input image as necessary with color values so that the matrix operations can be applied when the kernel is positioned at or near the edge of the input image.

        ''duplicate'' indicates that the input image is extended along each of its borders as necessary by duplicating the color values at the given edge of the input image.

        Original N-by-M image, where m=M-1 and n=N-1:

        <pre class=include>path: mathml/feConvolveMatrix04.mml</pre>

        Extended by two pixels using ''duplicate'':

        <pre class=include>path: mathml/feConvolveMatrix05.mml</pre>

        <a attr-value>wrap</a> indicates that the input image is extended by taking the color values from the opposite edge of the image.

        Extended by two pixels using <a attr-value>wrap</a>:

        <pre class=include>path: mathml/feConvolveMatrix06.mml</pre>

        <a attr-value>mirror</a> indicates that the input image is extended by taking color values mirrored across the edge being sampled beyond.

        Extended by two pixels using <a attr-value>mirror</a>:

        <pre class=include>path: mathml/feConvolveMatrix07.mml</pre>

        The value ''feConvolveMatrix/none'' indicates that the input image is extended with pixel values of zero for R, G, B and A.

        The <a for=svg>initial value</a> for <a element-attr for=feConvolveMatrix>edgeMode</a> is ''duplicate''.

        Animatable: yes.
    : <dfn element-attr dfn-for=feConvolveMatrix>kernelUnitLength</dfn> = "<em><<number-optional-number>></em>"
    ::
        The first number is the &lt;dx&gt; value. The second number is the &lt;dy&gt; value. If the &lt;dy&gt; value is not specified, it defaults to the same value as &lt;dx&gt;. Indicates the intended distance in current filter units (i.e., units as determined by the value of attribute <a element-attr>primitiveUnits</a>) between successive columns and rows, respectively, in the <a element-attr>kernelMatrix</a>. By specifying value(s) for <a element-attr for=feConvolveMatrix>kernelUnitLength</a>, the kernel becomes defined in a scalable, abstract coordinate system. If <a element-attr for=feConvolveMatrix>kernelUnitLength</a> is not specified, the default value is one pixel in the offscreen bitmap, which is a pixel-based coordinate system, and thus potentially not scalable. For some level of consistency across display media and user agents, it is necessary that a value be provided for <a element-attr for=feConvolveMatrix>kernelUnitLength</a>. In some implementations, the most consistent results and the fastest performance will be achieved if the pixel grid of the temporary off-screen images aligns with the pixel grid of the kernel.

        If a negative or zero value is specified the default value will be used instead.

        Note: This attribute is deprecated and will be removed. It does not provide a reliable way to create platform independent results. Future versions of this specification will cover this use case.

        Animatable: yes.
    : <dfn>preserveAlpha</dfn> = "<em>false | true</em>"
    ::
        A value of ''false'' indicates that the convolution will apply to all channels, including the alpha channel. In this case the <code>ALPHA<sub>X,Y</sub></code> of the <a href="#feConvolveMatrixElementFormula">convolution formula</a> for a given pixel is:

        <code>
            ALPHA<sub>X,Y</sub>&nbsp;=&nbsp;(&nbsp;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SUM
            <sub>I=0&nbsp;to&nbsp;[<a href=
            "#element-attrdef-order">orderY</a>-1]</sub>&nbsp;{&nbsp;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SUM
            <sub>J=0&nbsp;to&nbsp;[<a href=
            "#element-attrdef-order">orderX</a>-1]</sub>&nbsp;{&nbsp;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SOURCE
            <sub>X-<a element-attr>targetX</a>+J,&nbsp;Y-<a element-attr>targetY</a>+I</sub>&nbsp;*&nbsp;
            <a element-attr>kernelMatrix</a><sub><a href=
            "#element-attrdef-order">orderX</a>-J-1,&nbsp; <a href=
            "#element-attrdef-order">orderY</a>-I-1</sub>&nbsp;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)&nbsp;/&nbsp;
            <a element-attr>divisor</a>&nbsp;+&nbsp; <a element-attr>bias</a>&nbsp;<br>
        </code>

        A value of "true" indicates that the convolution will only apply to the color channels. In this case, the filter will temporarily unpremultiply the color component values and apply the kernel. In this case the <code>ALPHA<sub>X,Y</sub></code> of the <a href="#feConvolveMatrixElementFormula">convolution formula</a> for a given pixel is:

        <code>ALPHA<sub>X,Y</sub>&nbsp;=&nbsp;SOURCE<sub>X,Y</sub></code>

        The <a for=svg>initial value</a> for <a element-attr for=feConvolveMatrix>preserveAlpha</a> is ''false''.

        Animatable: yes.
</dl>


## Filter primitive <a element>feDiffuseLighting</a> ## {#feDiffuseLightingElement}

<pre class=include>
path: templates/effect-lighting.md
macros:
    name: feDiffuseLighting
    interface: SVGFEDiffuseLightingElement
    attributes: <li><a element-attr for=feDiffuseLighting>surfaceScale</a></li><li><a element-attr for=feDiffuseLighting>diffuseConstant</a></li><li><a element-attr for=feDiffuseLighting>kernelUnitLength</a></li>
</pre>

This filter primitive lights an image using the alpha channel as a bump map. The resulting image is an RGBA opaque image based on the light color with alpha = 1.0 everywhere. The lighting calculation follows the standard diffuse component of the Phong lighting model. The resulting image depends on the light color, light position and surface geometry of the input bump map.

The light map produced by this filter primitive can be combined with a texture image using the multiply term of the <em>arithmetic</em> <a element>feComposite</a> compositing method. Multiple <a>light sources</a> can be simulated by adding several of these light maps together before applying it to the texture image.

The formulas below make use of 3x3 filters. Because they operate on pixels, such filters are inherently resolution-dependent. To make <a element>feDiffuseLighting</a> produce resolution-independent results, an explicit value should be provided for the attribute <a element-attr for=feDiffuseLighting>kernelUnitLength</a>.

<a element-attr for=feDiffuseLighting>kernelUnitLength</a>, in combination with the other attributes, defines an implicit pixel grid in the filter effects coordinate system (i.e., the coordinate system established by the <a element-attr>primitiveUnits</a> attribute). The input image will be temporarily rescaled to match its pixels with <a element-attr for=feDiffuseLighting>kernelUnitLength</a>. The 3x3 filters are applied to the resampled image. After applying the filter, the image is resampled back to its original resolution.

Note: Depending on the speed of the available interpolates, this choice may be affected by the 'image-rendering' property setting.

Note: Implementations might choose approaches that minimize or eliminate resampling when not necessary to produce proper results, such as when the document is zoomed out such that <a element-attr for=feDiffuseLighting>kernelUnitLength</a> is considerably smaller than a device pixel.

For the formulas that follow, the <code>Norm(A<sub>x</sub>,A<sub>y</sub>,A<sub>z</sub>)</code> function is defined as:

<math> <semantics> <mrow> <mi mathvariant="italic">Norm</mi> <mrow> <mrow> <mo stretchy="false">(</mo> <mrow> <msub> <mi>A</mi> <mi>x</mi> </msub> <mi>,</mi> <msub> <mi>A</mi> <mi>y</mi> </msub> <mi>,</mi> <msub> <mi>A</mi> <mi>z</mi> </msub> </mrow> <mo stretchy="false">)</mo> </mrow> <mo stretchy="false">=</mo> <msqrt> <mrow> <mrow> <mrow> <msubsup> <mi>A</mi> <mi>x</mi> <mn>2</mn> </msubsup> <mo stretchy="false">+</mo> <msubsup> <mi>A</mi> <mi>y</mi> <mn>2</mn> </msubsup> </mrow> <mo stretchy="false">+</mo> <msubsup> <mi>A</mi> <mi>z</mi> <mn>2</mn> </msubsup> </mrow> </mrow> </msqrt> </mrow> </mrow> <annotation encoding="StarMath 5.0">Norm(A_x,A_y,A_z) = sqrt { A_x^2+A_y^2+A_z^2}</annotation> </semantics> </math>

Note: User agents may use the the "fast inverse square root" to optimize the equation and avoid time differences on extrema color values. See <a href="#priv-sec">Privacy and Security Considerations</a> section for more details about timing attacks.

The resulting RGBA image is computed as follows:

<code>
  D<sub>r</sub> = k<sub>d</sub> * N.L * L<sub>r</sub><br>
  D<sub>g</sub> = k<sub>d</sub> * N.L * L<sub>g</sub><br>
  D<sub>b</sub> = k<sub>d</sub> * N.L * L<sub>b</sub><br>
  D<sub>a</sub> = 1.0
</code>

where

k<sub>d</sub> = diffuse lighting constant<br>
N = surface normal unit vector, a function of x and y<br>
L = unit vector pointing from surface to light, a function of x and y in the point and spot light cases<br>
L<sub>r</sub>,L<sub>g</sub>,L<sub>b</sub> = RGB components of light, a function of x and y in the spot light case

N is a function of x and y and depends on the surface gradient as follows:

The surface described by the input alpha image I(x,y) is:

<code>Z (x,y) = surfaceScale * I(x,y)</code>

<p id="SurfaceNormalCalculations">Surface normal is calculated using the Sobel gradient 3x3 filter. Different filter kernels are used depending on whether the given pixel is on the interior or an edge. For each case, the formula is:</p>

<code>
  N<sub>x</sub> (x,y) = - surfaceScale * FACTOR<sub>x</sub> *<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(K<sub>x</sub>(0,0)*I(x-dx,y-dy)&nbsp;+
  K<sub>x</sub>(1,0)*I(x,y-dy)&nbsp;+ K<sub>x</sub>(2,0)*I(x+dx,y-dy)&nbsp;+<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K<sub>x</sub>(0,1)*I(x-dx,y)&nbsp;&nbsp;&nbsp;&nbsp;+
  K<sub>x</sub>(1,1)*I(x,y)&nbsp;&nbsp;&nbsp;&nbsp;+
  K<sub>x</sub>(2,1)*I(x+dx,y)&nbsp;&nbsp;&nbsp;&nbsp;+<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K<sub>x</sub>(0,2)*I(x-dx,y+dy)&nbsp;+
  K<sub>x</sub>(1,2)*I(x,y+dy)&nbsp;+ K<sub>x</sub>(2,2)*I(x+dx,y+dy))<br>
  N<sub>y</sub> (x,y) = - surfaceScale * FACTOR<sub>y</sub> *<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(K<sub>y</sub>(0,0)*I(x-dx,y-dy)&nbsp;+
  K<sub>y</sub>(1,0)*I(x,y-dy)&nbsp;+ K<sub>y</sub>(2,0)*I(x+dx,y-dy)&nbsp;+<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K<sub>y</sub>(0,1)*I(x-dx,y)&nbsp;&nbsp;&nbsp;&nbsp;+
  K<sub>y</sub>(1,1)*I(x,y)&nbsp;&nbsp;&nbsp;&nbsp;+
  K<sub>y</sub>(2,1)*I(x+dx,y)&nbsp;&nbsp;&nbsp;&nbsp;+<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;K<sub>y</sub>(0,2)*I(x-dx,y+dy)&nbsp;+
  K<sub>y</sub>(1,2)*I(x,y+dy)&nbsp;+ K<sub>y</sub>(2,2)*I(x+dx,y+dy))<br>
  N<sub>z</sub> (x,y) = 1.0<br>
  <br>
  N = (N<sub>x</sub>, N<sub>y</sub>, N<sub>z</sub>) /
  Norm((N<sub>x</sub>,N<sub>y</sub>,N<sub>z</sub>))
</code>

In these formulas, the <code>dx</code> and <code>dy</code> values (e.g., <code>I(x-dx,y-dy)</code>), represent deltas relative to a given <code>(x,y)</code> position for the purpose of estimating the slope of the surface at that point. These deltas are determined by the value (explicit or implicit) of attribute <a element-attr for=feDiffuseLighting>kernelUnitLength</a>.

<table class="data complex">
  <tbody>
    <tr>
      <th>
        Top/left corner:
      </th>
      <th>
        Top row:
      </th>
      <th>
        Top/right corner:
      </th>
    </tr>
    <tr>
      <td>
        <p class="filterformula">
          FACTOR<sub>x</sub>=2/(3*dx)<br>
          K<sub>x</sub> =<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;-2&nbsp;&nbsp;2&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;-1&nbsp;&nbsp;1&nbsp;|<br>
          <br>
          FACTOR<sub>y</sub>=2/(3*dy)<br>
          K<sub>y</sub>&nbsp;=&nbsp;&nbsp;<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;-2&nbsp;-1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;2&nbsp;&nbsp;1&nbsp;|
        </p>
      </td>
      <td>
        <p class="filterformula">
          FACTOR<sub>x</sub>=1/(3*dx)<br>
          K<sub>x</sub> =<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-2&nbsp;&nbsp;0&nbsp;&nbsp;2&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;&nbsp;0&nbsp;&nbsp;1&nbsp;|<br>
          <br>
          FACTOR<sub>y</sub>=1/(2*dy)<br>
          K<sub>y</sub>&nbsp;=&nbsp;&nbsp;<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;-2&nbsp;-1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;1&nbsp;&nbsp;2&nbsp;&nbsp;1&nbsp;|
        </p>
      </td>
      <td>
        <p class="filterformula">
          FACTOR<sub>x</sub>=2/(3*dx)<br>
          K<sub>x</sub> =<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-2&nbsp;&nbsp;2&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;&nbsp;1&nbsp;&nbsp;0&nbsp;|<br>
          <br>
          FACTOR<sub>y</sub>=2/(3*dy)<br>
          K<sub>y</sub>&nbsp;=&nbsp;&nbsp;<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;-2&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;1&nbsp;&nbsp;2&nbsp;&nbsp;0&nbsp;|
        </p>
      </td>
    </tr>
    <tr>
      <th>
        Left column:
      </th>
      <th>
        Interior pixels:
      </th>
      <th>
        Right column:
      </th>
    </tr>
    <tr>
      <td>
        <p class="filterformula">
          FACTOR<sub>x</sub>=1/(2*dx)<br>
          K<sub>x</sub> =<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;0&nbsp;-1&nbsp;&nbsp;1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;0&nbsp;-2&nbsp;&nbsp;2&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;0&nbsp;-1&nbsp;&nbsp;1&nbsp;|<br>
          <br>
          FACTOR<sub>y</sub>=1/(3*dy)<br>
          K<sub>y</sub>&nbsp;=&nbsp;&nbsp;<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;-2&nbsp;-1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;2&nbsp;&nbsp;1&nbsp;|
        </p>
      </td>
      <td>
        <p class="filterformula">
          FACTOR<sub>x</sub>=1/(4*dx)<br>
          K<sub>x</sub> =<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;&nbsp;0&nbsp;&nbsp;1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-2&nbsp;&nbsp;0&nbsp;&nbsp;2&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;&nbsp;0&nbsp;&nbsp;1&nbsp;|<br>
          <br>
          FACTOR<sub>y</sub>=1/(4*dy)<br>
          K<sub>y</sub>&nbsp;=&nbsp;&nbsp;<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;-2&nbsp;-1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;1&nbsp;&nbsp;2&nbsp;&nbsp;1&nbsp;|
        </p>
      </td>
      <td>
        <p class="filterformula">
          FACTOR<sub>x</sub>=1/(2*dx)<br>
          K<sub>x</sub> =<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;&nbsp;1&nbsp;&nbsp;0|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-2&nbsp;&nbsp;2&nbsp;&nbsp;0|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;&nbsp;1&nbsp;&nbsp;0|<br>
          <br>
          FACTOR<sub>y</sub>=1/(3*dy)<br>
          K<sub>y</sub>&nbsp;=&nbsp;&nbsp;<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;-2&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;1&nbsp;&nbsp;2&nbsp;&nbsp;0&nbsp;|
        </p>
      </td>
    </tr>
    <tr>
      <th>
        Bottom/left corner:
      </th>
      <th>
        Bottom row:
      </th>
      <th>
        Bottom/right corner:
      </th>
    </tr>
    <tr>
      <td>
        <p class="filterformula">
          FACTOR<sub>x</sub>=2/(3*dx)<br>
          K<sub>x</sub> =<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;0&nbsp;-1&nbsp;&nbsp;1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;0&nbsp;-2&nbsp;&nbsp;2&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          <br>
          FACTOR<sub>y</sub>=2/(3*dy)<br>
          K<sub>y</sub>&nbsp;=&nbsp;&nbsp;<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;-2&nbsp;-1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;2&nbsp;&nbsp;1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|
        </p>
      </td>
      <td>
        <p class="filterformula">
          FACTOR<sub>x</sub>=1/(3*dx)<br>
          K<sub>x</sub> =<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;&nbsp;0&nbsp;&nbsp;1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-2&nbsp;&nbsp;0&nbsp;&nbsp;2&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          <br>
          FACTOR<sub>y</sub>=1/(2*dy)<br>
          K<sub>y</sub>&nbsp;=&nbsp;&nbsp;<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;-2&nbsp;-1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;1&nbsp;&nbsp;2&nbsp;&nbsp;1&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|
        </p>
      </td>
      <td>
        <p class="filterformula">
          FACTOR<sub>x</sub>=2/(3*dx)<br>
          K<sub>x</sub> =<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;&nbsp;1&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-2&nbsp;&nbsp;2&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|<br>
          <br>
          FACTOR<sub>y</sub>=2/(3*dy)<br>
          K<sub>y</sub>&nbsp;=&nbsp;&nbsp;<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;-1&nbsp;-2&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;1&nbsp;&nbsp;2&nbsp;&nbsp;0&nbsp;|<br>
          &nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;&nbsp;0&nbsp;|
        </p>
      </td>
    </tr>
  </tbody>
</table>

L, the unit vector from the image sample to the light, is calculated as follows:

For Infinite <a>light sources</a> it is constant:

<code>
  L<sub>x</sub> = cos(azimuth)*cos(elevation)<br>
  L<sub>y</sub> = sin(azimuth)*cos(elevation)<br>
  L<sub>z</sub> = sin(elevation)
</code>

For Point and spot lights it is a function of position:

<code>
  L<sub>x</sub> = Light<sub>x</sub> - x<br>
  L<sub>y</sub> = Light<sub>y</sub> - y<br>
  L<sub>z</sub> = Light<sub>z</sub> - Z(x,y)<br>
  <br>
  L = (L<sub>x</sub>, L<sub>y</sub>, L<sub>z</sub>) / Norm(L<sub>x</sub>,
  L<sub>y</sub>, L<sub>z</sub>)
</code>

where Light<sub>x</sub>, Light<sub>y</sub>, and Light<sub>z</sub> are the input light position.

L<sub>r</sub>,L<sub>g</sub>,L<sub>b</sub>, the light color vector, is a function of position in the spot light case only:

<code>
  L<sub>r</sub> = Light<sub>r</sub>*pow((-L.S),specularExponent)<br>
  L<sub>g</sub> = Light<sub>g</sub>*pow((-L.S),specularExponent)<br>
  L<sub>b</sub> = Light<sub>b</sub>*pow((-L.S),specularExponent)
</code>

where S is the unit vector pointing from the light to the point (pointsAtX, pointsAtY, pointsAtZ) in the x-y plane:

<code>
  S<sub>x</sub> = pointsAtX - Light<sub>x</sub><br>
  S<sub>y</sub> = pointsAtY - Light<sub>y</sub><br>
  S<sub>z</sub> = pointsAtZ - Light<sub>z</sub><br>
  <br>
  S = (S<sub>x</sub>, S<sub>y</sub>, S<sub>z</sub>) / Norm(S<sub>x</sub>,
  S<sub>y</sub>, S<sub>z</sub>)
</code>

If L.S is positive, no light is present. (L<sub>r</sub> = L<sub>g</sub> = L<sub>b</sub> = 0). If <a element-attr>limitingConeAngle</a> is specified, -L.S &lt; cos(limitingConeAngle) also indicates that no light is present.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feDiffuseLighting>
    : <dfn>surfaceScale</dfn> = "<em><<number>></em>"
    ::
        height of surface when A<sub>in</sub> = 1.

        If the attribute is not specified, then the effect is as if a value of ''1'' were specified.

        Animatable: yes.
    : <dfn>diffuseConstant</dfn> = "<em><<number>></em>"
    ::
        kd in Phong lighting model. In SVG, this can be any non-negative number.

        If the attribute is not specified, then the effect is as if a value of ''1'' were specified.

        Animatable: yes.
    : <dfn>kernelUnitLength</dfn> = "<em><<number-optional-number>></em>"
    ::
        The first number is the &lt;dx&gt; value. The second number is the &lt;dy&gt; value. If the &lt;dy&gt; value is not specified, it defaults to the same value as &lt;dx&gt;. Indicates the intended distance in current filter units (i.e., units as determined by the value of attribute <a element-attr>primitiveUnits</a>) for <code>dx</code> and <code>dy</code>, respectively, in the <a href="#SurfaceNormalCalculations">surface normal calculation formulas</a>. By specifying value(s) for <a element-attr for=feDiffuseLighting>kernelUnitLength</a>, the kernel becomes defined in a scalable, abstract coordinate system. If <a element-attr for=feDiffuseLighting>kernelUnitLength</a> is not specified, the <code>dx</code> and <code>dy</code> values should represent very small deltas relative to a given <code>(x,y)</code> position, which might be implemented in some cases as one pixel in the intermediate image offscreen bitmap, which is a pixel-based coordinate system, and thus potentially not scalable. For some level of consistency across display media and user agents, it is necessary that a value be provided for <a element-attr for=feDiffuseLighting>kernelUnitLength</a>.

        If a negative or zero value is specified the default value will be used instead.

        Note: This attribute is deprecated and will be removed. It does not provide a reliable way to create platform independent results. Future versions of this specification will cover this use case.

        Animatable: yes.

</dl>

The <a>light source</a> is defined by one of the child elements <a element>feDistantLight</a>, <a element>fePointLight</a> or <a element>feSpotLight</a>. The light color is specified by property 'lighting-color'.

## Filter primitive <a element>feDisplacementMap</a> ## {#feDisplacementMapElement}

<pre class=include>
path: templates/effect-in2.md
macros:
    name: feDisplacementMap
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFEDisplacementMapElement
    attributes: <li><a element-attr for=feDisplacementMap>scale</a></li><li><a element-attr for=feDisplacementMap>xChannelSelector</a></li><li><a element-attr for=feDisplacementMap>yChannelSelector</a></li>
</pre>

Issue(113): Implementations do not match specification.

This filter primitive uses the pixels values from the image from <a element-attr for=feDisplacementMap>in2</a> to spatially displace the image from <a element-attr>in</a>. This is the transformation to be performed:

<pre>
P'(x,y) &#8592; P( x + scale * (XC(x,y) - .5), y + scale * (YC(x,y) - .5))
</pre>

where P(x,y) is the input image, <a element-attr>in</a>, and P'(x,y) is the destination. XC(x,y) and YC(x,y) are the component values of the channel designated by the <a element-attr>xChannelSelector</a> and <a element-attr>yChannelSelector</a>. For example, to use the R component of <a element-attr for=feDisplacementMap>in2</a> to control displacement in x and the G component of Image2 to control displacement in y, set <a element-attr>xChannelSelector</a> to "R" and <a element-attr>yChannelSelector</a> to "G".

The displacement map, <a element-attr for=feDisplacementMap>in2</a>, defines the inverse of the mapping performed.

The input image <a element-attr>in</a> is to remain premultiplied for this filter primitive. The calculations using the pixel values from <a element-attr for=feDisplacementMap>in2</a> are performed using non-premultiplied color values.

This filter can have arbitrary non-localized effect on the input which might require substantial buffering in the processing pipeline. However with this formulation, any intermediate buffering needs can be determined by <a element-attr for=feDisplacementMap>scale</a> which represents the maximum range of displacement in either x or y.

When applying this filter, the source pixel location will often lie between several source pixels.

Note: Depending on the speed of the available interpolents, this choice may be affected by the 'image-rendering' property setting.

Note: A future version of this spec will define the interpolation method to be used when distorting the source image making UAs rendering result more interoperable.

The 'color-interpolation-filters' property only applies to the <a element-attr for=feDisplacementMap>in2</a> source image and does not apply to the <a element-attr>in</a> source image. The <a element-attr>in</a> source image must remain in its current color space.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feDisplacementMap>
    : <dfn>scale</dfn> = "<em><<number>></em>"
    ::
        Displacement scale factor. The amount is expressed in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element.

        When the value of this attribute is ''0'', this operation has no effect on the source image.

        The <a for=svg>initial value</a> for <a element-attr for=feDisplacementMap>scale</a> is ''0''.

        Animatable: yes.
    : <dfn>xChannelSelector</dfn> = "<em>R | G | B | A</em>"
    ::
        Indicates which channel from <a element-attr for=feDisplacementMap>in2</a> to use to displace the pixels in <a element-attr>in</a> along the x-axis.

        The <a for=svg>initial value</a> for <a element-attr>xChannelSelector</a> is ''xChannelSelector/A''.

        Animatable: yes.
    : <dfn>yChannelSelector</dfn> = "<em>R | G | B | A</em>"
    ::
        Indicates which channel from <a element-attr for=feDisplacementMap>in2</a> to use to displace the pixels in <a element-attr>in</a> along the y-axis.

        The <a for=svg>initial value</a> for <a element-attr>yChannelSelector</a> is ''yChannelSelector/A''.

        Animatable: yes.
    : <dfn>in2</dfn> = "<em>(see <a element-attr>in</a> attribute)</em>"
    ::
        The second input image, which is used to displace the pixels in the image from attribute <a element-attr>in</a>. See defintion for <a element-attr>in</a> attribute.

        Animatable: yes.
</dl>

## Filter primitive <a element>feDropShadow</a> ## {#feDropShadowElement}

<pre class=include>
path: templates/effect-in1.md
macros:
    name: feDropShadow
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFEDropShadowElement
    attributes: <li><a element-attr for=feDropShadow>stdDeviation</a></li><li><a element-attr for=feDropShadow>dx</a></li><li><a element-attr for=feDropShadow>dy</a></li>
</pre>

This filter creates a drop shadow of the input image. It is a shorthand filter, and is defined in terms of combinations of other <a>filter primitives</a>. The expectation is that it can be optimized more easily by implementations.

The result of a <a element>feDropShadow</a> filter primitive is equivalent to the following:

<pre><code highlight=svg>
    &lt;feGaussianBlur in="<b>alpha-channel-of-feDropShadow-in</b>"   stdDeviation="<b>stdDeviation-of-feDropShadow</b>"/&gt;
    &lt;feOffset dx="<b>dx-of-feDropShadow</b>"   dy="<b>dy-of-feDropShadow</b>" result="offsetblur"/&gt;
    &lt;feFlood flood-color="<b>flood-color-of-feDropShadow</b>"  flood-opacity="<b>flood-opacity-of-feDropShadow</b>"/&gt;
    &lt;feComposite in2="offsetblur" operator="in"/&gt;
    &lt;feMerge&gt;
      &lt;feMergeNode/&gt;
      &lt;feMergeNode in="<b>in-of-feDropShadow</b>"/&gt;
    &lt;/feMerge&gt;
</code></pre>

The above divided into steps:

1. Take the alpha channel of the input to the <a element>feDropShadow</a> filter primitive and the <a element-attr for=feDropShadow>stdDeviation</a> on the <a element>feDropShadow</a> and do processing as if the following <a element>feGaussianBlur</a> was applied:
    <pre><code highlight=svg>
        &lt;feGaussianBlur in="<b>alpha-channel-of-feDropShadow-in</b>" stdDeviation="<b>stdDeviation-of-feDropShadow</b>"/&gt;
    </code></pre>
2. Offset the result of step 1 by <a element-attr for=feDropShadow>dx</a> and <a element-attr for=feDropShadow>dy</a> as specified on the <a element>feDropShadow</a> element, equivalent to applying an <a element>feOffset</a> with these parameters:
    <pre><code highlight=svg>
        &lt;feOffset dx="<b>dx-of-feDropShadow</b>" dy="<b>dy-of-feDropShadow</b>" result="offsetblur"/&gt;
    </code></pre>
3. Do processing as if an <a element>feFlood</a> element with 'flood-color' and 'flood-opacity' as specified on the <a element>feDropShadow</a> was applied:
    <pre><code highlight=svg>
        &lt;feFlood flood-color="<b>flood-color-of-feDropShadow</b>" flood-opacity="<b>flood-opacity-of-feDropShadow</b>"/&gt;
    </code></pre>
4. Composite the result of the <a element>feFlood</a> in step 3 with the result of the <a element>feOffset</a> in step 2 as if an <a element>feComposite</a> filter primitive with <code>operator="in"</code> was applied:
    <pre><code highlight=svg>
        &lt;feComposite in2="offsetblur" operator="in"/&gt;
    </code></pre>
5. Finally merge the result of the previous step, doing processing as if the following <a element>feMerge</a> was performed:
    <pre><code highlight=svg>
        &lt;feMerge&gt;
          &lt;feMergeNode/&gt;
          &lt;feMergeNode in="<b>in-of-feDropShadow</b>"/&gt;
        &lt;/feMerge&gt;
    </code></pre>

Note: that while the definition of the <a element>feDropShadow</a> filter primitive says that it can be expanded into an equivalent tree it is not required that it is implemented like that. The expectation is that user agents can optimize the handling by not having to do all the steps separately.

Beyond the DOM interface <a href="#InterfaceSVGFEDropShadowElement">SVGFEDropShadowElement</a> there is no way of accessing the internals of the <a element>feDropShadow</a> filter primitive, meaning <span class="requirement" id="assert_dropShadowShadowTrees">if the filter primitive is implemented as an equivalent tree then that tree must not be exposed to the DOM.</span>

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feDropShadow>
    : <dfn>dx</dfn> = "<em><<number>></em>"
    ::
        The x offset of the drop shadow.

        The <a for=svg>initial value</a> for <a element-attr for=feDropShadow>dx</a> is ''2''.

        This attribute is then forwarded to the <a element-attr for=feOffset>dx</a> attribute of the internal <a element>feOffset</a> element.

        Animatable: yes.
    : <dfn>dy</dfn> = "<em><<number>></em>"
    ::
        The y offset of the drop shadow.

        The <a for=svg>initial value</a> for <a element-attr for=feDropShadow>dy</a> is ''2''.

        This attribute is then forwarded to the <a element-attr for=feOffset>dy</a> attribute of the internal <a element>feOffset</a> element.

        Animatable: yes.
    : <dfn>stdDeviation</dfn> = "<em><<number-optional-number>></em>"
    ::
        The standard deviation for the blur operation in the drop shadow.

        The <a for=svg>initial value</a> for <a element-attr for=feDropShadow>stdDeviation</a> is ''2''.

        This attribute is then forwarded to the <a element-attr for=feGaussianBlur>stdDeviation</a> attribute of the internal <a element>feGaussianBlur</a> element.

        Animatable: yes.
</dl>


## Filter primitive <a element>feFlood</a> ## {#feFloodElement}

<pre class=include>
path: templates/effect.md
macros:
    name: feFlood
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFEFloodElement
</pre>

This filter primitive creates a rectangle filled with the color and opacity values from properties 'flood-color' and 'flood-opacity'. The rectangle is as large as the <a>filter primitive subregion</a> established by the <a element>feFlood</a> element.


### The 'flood-color' property ### {#FloodColorProperty}

<pre class='propdef'>
Name: flood-color
Value: <<color>>
Initial: black
Applies to: <a element>feFlood</a> and <a element>feDropShadow</a> elements
Inherited: no
Percentages: n/a
Computed value: as specified
Media: visual
Animation type: by computed value
</pre>

The 'flood-color' property indicates what color to used to flood the current <a>filter primitive subregion</a>.

The 'flood-color' property is a <a href="https://www.w3.org/TR/2011/REC-SVG11-20110816/intro.html#TermPresentationAttribute">presentation attribute</a> for SVG elements.

### The 'flood-opacity' property ### {#FloodOpacityProperty}

<pre class='propdef'>
Name: flood-opacity
Value: <<'opacity'>>
Initial: 1
Applies to: <a element>feFlood</a> and <a element>feDropShadow</a> elements
Inherited: no
Percentages: n/a
Computed value: the specified value converted to a number, clamped to the range [0,1]
Media: visual
Animation type: by computed value
</pre>

The 'flood-opacity' property defines the opacity value to use across the entire <a>filter primitive subregion</a>. If the 'flood-color' value includes an alpha channel, the alpha channel gets multiplied with the computed value of the 'flood-opacity' property.

The 'flood-opacity' property is a <a href="https://www.w3.org/TR/2011/REC-SVG11-20110816/intro.html#TermPresentationAttribute">presentation attribute</a> for SVG elements.

## Filter primitive <a element>feGaussianBlur</a> ## {#feGaussianBlurElement}

<pre class=include>
path: templates/effect-in1.md
macros:
    name: feGaussianBlur
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFEGaussianBlurElement
    attributes: <li><a element-attr for=feGaussianBlur>stdDeviation</a></li><li><a element-attr for=feGaussianBlur>edgeMode</a></li>
</pre>

This filter primitive performs a Gaussian blur on the input image.

The Gaussian blur kernel is an approximation of the normalized convolution:

<code>G(x,y) = H(x)I(y)</code>

where

<code>H(x) = exp(-x<sup>2</sup>/ (2s<sup>2</sup>)) / sqrt(2&pi; * s<sup>2</sup>)</code>

and

<code>I(y) = exp(-y<sup>2</sup>/ (2t<sup>2</sup>)) / sqrt(2&pi; * t<sup>2</sup>)</code>

with "s" being the standard deviation in the x direction and "t" being the standard deviation in the y direction, as specified by <a element-attr for=feGaussianBlur>stdDeviation</a>.

The value of <a element-attr for=feGaussianBlur>stdDeviation</a> can be either one or two numbers. If two numbers are provided, the first number represents a standard deviation value along the x-axis of the current coordinate system and the second value represents a standard deviation in Y. If one number is provided, then that value is used for both X and Y.

Even if only one value is provided for <a element-attr for=feGaussianBlur>stdDeviation</a>, this can be implemented as a separable convolution.

For larger values of "s" (s &gt;= 2.0), an approximation can be used: Three successive box-blurs build a piece-wise quadratic convolution kernel, which approximates the Gaussian kernel to within roughly 3%.

<code>let d = floor(s * 3 * sqrt(2 * &pi;) / 4 + 0.5)</code>

... if d is odd, use three box-blurs of size "d", centered on the output pixel.

... if d is even, two box-blurs of size "d" (the first one centered on the pixel boundary between the output pixel and the one to the left, the second one centered on the pixel boundary between the output pixel and the one to the right) and one box blur of size "d+1" centered on the output pixel.

The approximation formula also applies correspondingly to "t".

Frequently this operation will take place on alpha-only images, such as that produced by the built-in input, <a attr-value>SourceAlpha</a>. The implementation may notice this and optimize the single channel case. This optimization must be omitted if it leads to privacy concerns of any matter. (See section <a href="#priv-sec">Privacy and Security Considerations</a> for more details about timing attacks.) If the input has infinite extent and is constant (e.g <a attr-value>FillPaint</a> where the fill is a solid color), this operation has no effect. If the input has infinite extent and the filter result where the fill is a solid color) is the input to an <a element>feTile</a>, the filter is evaluated with <a href="http://en.wikipedia.org/wiki/Periodic_boundary_conditions">periodic boundary conditions</a>.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feGaussianBlur>
    : <dfn>stdDeviation</dfn> = "<em><<number-optional-number>></em>"
    ::
        The standard deviation for the blur operation. If two <<number>> s are provided, the first number represents a standard deviation value along the x-axis of the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element. The second value represents a standard deviation in Y. If one number is provided, then that value is used for both X and Y.

        A negative value or a value of zero disables the effect of the given filter primitive (i.e., the result is the filter input image).

        If <a element-attr for=feGaussianBlur>stdDeviation</a> is ''0'' in only one of X or Y, then the effect is that the blur is only applied in the direction that has a non-zero value.

        The <a for=svg>initial value</a> for <a element-attr for=feGaussianBlur>stdDeviation</a> is ''0''.

        Animatable: yes.
    : <dfn>edgeMode</dfn> = "<a attr-value>duplicate</a> | <a attr-value>wrap</a> | <a attr-value>mirror</a> | none"
    ::
        Determines how to extend the input image as necessary with color values so that the matrix operations can be applied when the kernel is positioned at or near the edge of the input image.

        <dfn dfn-type=attr-value dfn-for=feGaussianBlur/edgeMode>duplicate</dfn> indicates that the input image is extended along each of its borders as necessary by duplicating the color values at the given edge of the input image.

        Original N-by-M image, where m=M-1 and n=N-1:

        <dfn dfn-type=attr-value dfn-for=feGaussianBlur/edgeMode>wrap</dfn> indicates that the input image is extended by taking the color values from the opposite edge of the image.

        <dfn dfn-type=attr-value dfn-for=feGuassianBlur/edgeMode>mirror</dfn> indicates that the input image is extended by taking color values mirrored across the edge being sampled beyond.

        The value ''feGaussianBlur/none'' indicates that the input image is extended with pixel values of zero for R, G, B and A.

        The <a for=svg>initial value</a> for <a element-attr for=feGaussianBlur>edgeMode</a> is ''feGaussianBlur/none''.

        Animatable: yes.
</dl>

<a href="#intro">The example</a> at the start of this chapter makes use of the <a element>feGaussianBlur</a> filter primitive to create a drop shadow effect.


## Filter primitive <a element>feImage</a> ## {#feImageElement}

<pre class=include>
path: templates/effect.md
macros:
    name: feImage
    model: <a element>animate</a>, <a element>animateTransform</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFEImageElement
    attributes: <li><a href='https://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#ExternalResourcesRequiredAttribute'><span class=attr-name>externalResourcesRequired</span></a></li><li><a element-attr for=feImage>preserveAspectRatio</a></li><li><a element-attr for=feImage>xlink:href</a></li><li><a element-attr for=feImage>href</a></li><li><a element-attr for=feImage>crossorigin</a></li>
</pre>

This filter primitive refers to a graphic external to this filter element, which is loaded or rendered into an RGBA raster and becomes the result of the filter primitive.

This filter primitive can refer to an external image or can be a reference to another piece of SVG. It produces an image similar to the built-in image source <a attr-value>SourceGraphic</a> except that the graphic comes from an external source.

If the <a element-attr for=feImage>href</a> references a stand-alone image resource such as a JPEG, PNG or SVG file, then the image resource is rendered according to the behavior of the <a element>image</a> element; otherwise, the referenced resource is rendered according to the behavior of the <a element>use</a> element. In either case, the current user coordinate system depends on the value of attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element. The processing of the <a element-attr for=feImage>preserveAspectRatio</a> attribute on the <a element>feImage</a> element is identical to that of the <a element>image</a> element.

A <a element-attr for=feImage>href</a> reference that is an empty image (zero width or zero height), that fails to download, is non-existent, or that cannot be displayed (e.g. because it is not in a supported image format) fills the filter primitive subregion with transparent black.

<span class="requirement" id="assert_hqImageResampling">When the referenced image must be resampled to match the device coordinate system, it is recommended that high quality viewers make use of appropriate interpolation techniques, for example bilinear or bicubic.</span> Depending on the speed of the available interpolents, this choice may be affected by the 'image-rendering' property setting.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feImage>
    : <dfn>xlink:href</dfn> = "<<filter/url>>"
    ::
        See <a element-attr for=feImage>href</a> attribute.

        Animatable: yes.

        Note: This <em>xlink:href</em> attribute is deprecated and should not be used in new content, it's included for backwards compatibility reasons only. Authors should use the <a element-attr for=feImage>href</a> attribute instead.
    : <dfn>href</dfn> = "<<filter/url>>"
    ::
        An <<filter/url>> to an image resource or to an element. If both, the <a element-attr for=feImage>xlink:href</a> and the <a element-attr for=feImage>href</a> attribute are specified, the latter overrides the first definition.

        Animatable: yes.
    : <dfn>preserveAspectRatio</dfn> = "<em>[defer] &lt;align&gt; [&lt;meetOrSlice&gt;]</em>"
    ::
        See <a element-attr for=feImage>preserveAspectRatio</a>.

        The <a for=svg>initial value</a> for <a element-attr for=feImage>preserveAspectRatio</a> is ''xMidYMid meet''.

        Animatable: yes.
    : <dfn>crossorigin</dfn> = "<em>anonymous</em> | <em>use-credentials</em>"
    ::
        The <a href="https://html.spec.whatwg.org/multipage/embedded-content.html#attr-img-crossorigin">crossorigin</a> attribute is a CORS settings attribute. Its purpose is to allow images from third-party sites that allow cross-origin access to be used with <a element>feDisplacementMap</a>. For the defintion see <a href="https://html.spec.whatwg.org/multipage/embedded-content.html#attr-img-crossorigin">crossorigin</a> attribute for the <a element>img</a> tag [[!HTML]] and the <a href="#priv-sec">Privacy and Security Considerations</a> section in this specification.

        Animatable: no.
</dl>

<div class=example>
    The following example illustrates how images are placed relative to an object. From left to right:

    * The default placement of an image. Note that the image is centered in the <a>filter region</a> and has the maximum size that will fit in the region consistent with preserving the aspect ratio.
    * The image stretched to fit the bounding box of an object.
    * The image placed using user coordinates. Note that the image is first centered in a box the size of the <a>filter region</a> and has the maximum size that will fit in the box consistent with preserving the aspect ratio. This box is then shifted by the given <a element-attr for=filter-primitive>x</a> and <a element-attr for=filter-primitive>y</a> values relative to the viewport the object is in.

    <pre><code highlight=svg>
        &lt;svg width="600" height="250" viewBox="0 0 600 250"
             xmlns="http://www.w3.org/2000/svg"
             xmlns:xlink="http://www.w3.org/1999/xlink"&gt;
          &lt;title&gt;Example feImage - Examples of feImage use&lt;/title&gt;
          &lt;desc&gt;Three examples of using feImage, the first showing the
                default rendering, the second showing the image fit
                to a box and the third showing the image
                shifted and clipped.&lt;/desc&gt;
          &lt;defs&gt;
            &lt;filter id="Default"&gt;
              &lt;feImage xlink:href="smiley.png" /&gt;
            &lt;/filter&gt;
            &lt;filter id="Fitted" primitiveUnits="objectBoundingBox"&gt;
              &lt;feImage xlink:href="smiley.png"
                 x="0" y="0" width="100%" height="100%"
                 preserveAspectRatio="none"/&gt;
            &lt;/filter&gt;
            &lt;filter id="Shifted"&gt;
              &lt;feImage xlink:href="smiley.png"
                 x="500" y="5"/&gt;
            &lt;/filter&gt;
          &lt;/defs&gt;
          &lt;rect fill="none" stroke="blue"
                x="1" y="1" width="598" height="248"/&gt;
          &lt;g&gt;
            &lt;rect x="50"  y="25" width="100" height="200" filter="url(#Default)"/&gt;
            &lt;rect x="50"  y="25" width="100" height="200" fill="none" stroke="green"/&gt;
            &lt;rect x="250" y="25" width="100" height="200" filter="url(#Fitted)"/&gt;
            &lt;rect x="250" y="25" width="100" height="200" fill="none" stroke="green"/&gt;
            &lt;rect x="450" y="25" width="100" height="200" filter="url(#Shifted)"/&gt;
            &lt;rect x="450" y="25" width="100" height="200" fill="none" stroke="green"/&gt;
          &lt;/g&gt;
        &lt;/svg&gt;
    </code></pre>

    <div class=figure>
        <img alt="Example feImage &mdash; Examples of feImage use" src="examples/feImage-01.png">
        <p class=caption>Example of feImage</p>
    </div>

    <a href="examples/feImage-01.svg">View this example as SVG</a>
</div>


## Filter primitive <a element>feMerge</a> ## {#feMergeElement}

<pre class=include>
path: templates/effect.md
macros:
    name: feMerge
    model: <a element>feMergeNode</a>, <a element>script</a>
    interface: SVGFEMergeElement
</pre>

This filter primitive composites input image layers on top of each other using the <em>over</em> operator with <em>Input1</em> (corresponding to the first <a element>feMergeNode</a> child element) on the bottom and the last specified input, <em>InputN</em> (corresponding to the last <a element>feMergeNode</a> child element), on top.

Many effects produce a number of intermediate layers in order to create the final output image. This filter allows us to collapse those into a single image. Although this could be done by using n-1 Composite-filters, it is more convenient to have this common operation available in this form, and offers the implementation some additional flexibility.

Each <a element>feMerge</a> element can have any number of <a element>feMergeNode</a> subelements, each of which has an <a element-attr>in</a> attribute.

The canonical implementation of feMerge is to render the entire effect into one RGBA layer, and then render the resulting layer on the output device. In certain cases (in particular if the output device itself is a continuous tone device), and since merging is associative, it might be a sufficient approximation to evaluate the effect one layer at a time and render each layer individually onto the output device bottom to top.

If the topmost image input is <a attr-value>SourceGraphic</a> and this <a element>feMerge</a> is the last filter primitive in the filter, the implementation is encouraged to render the layers up to that point, and then render the <a attr-value>SourceGraphic</a> directly from its vector description on top.

<a href="#intro">The example</a> at the start of this chapter makes use of the <a element>feMerge</a> filter primitive to composite two intermediate filter results together.


### Merge node <a element>feMergeNode</a> ### {#feMergeNodeElement}

<pre class=include>
path: templates/effect-source.md
macros:
    name: feMergeNode
    interface: SVGFEMergeNodeElement
    catagories: None.
    attributes: <li><a element-attr for=filter-primitive>in</a></li>
</pre>

## Filter primitive <a element>feMorphology</a> ## {#feMorphologyElement}

<pre class=include>
path: templates/effect-in1.md
macros:
    name: feMorphology
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFEMorphologyElement
    attributes: <li><a element-attr for=feMorphology>operator</a></li><li><a element-attr for=feMorphology>radius</a></li>
</pre>

This filter primitive performs "fattening" or "thinning" of artwork. It is particularly useful for fattening or thinning an alpha channel.

The dilation (or erosion) kernel is a rectangle with a width of 2*<em>x-radius</em> and a height of 2*<em>y-radius</em>. In dilation, the output pixel is the individual component-wise maximum of the corresponding R,G,B,A values in the input image's kernel rectangle. In erosion, the output pixel is the individual component-wise minimum of the corresponding R,G,B,A values in the input image's kernel rectangle.

Frequently this operation will take place on alpha-only images, such as that produced by the built-in input, <a attr-value>SourceAlpha</a>. In that case, the implementation might want to optimize the single channel case. This optimization must be omitted if it leads to privacy concerns of any matter. (See section <a href="#priv-sec">Privacy and Security Considerations</a> for more details.)

If the input has infinite extent and is constant (e.g <a attr-value>FillPaint</a> where the fill is a solid color), this operation has no effect. If the input has infinite extent and the filter result is the input to an <a element>feTile</a>, the filter is evaluated with <a href="http://en.wikipedia.org/wiki/Periodic_boundary_conditions">periodic boundary conditions</a>.

Because <a element>feMorphology</a> operates on premultipied color values, it will always result in color values less than or equal to the alpha channel.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feMorphology>
    : <dfn>operator</dfn> = "<em>erode | dilate</em>"
    ::
        A keyword indicating whether to erode (i.e., thin) or dilate (fatten) the source graphic.

        The <a for=svg>initial value</a> for <a element-attr for=feMorphology>operator</a> is ''erode''.

        Animatable: yes.
    : <dfn>radius</dfn> = "<em><<number-optional-number>></em>"
    ::
        The radius (or radii) for the operation. If two <<number>> s are provided, the first number represents a x-radius and the second value represents a y-radius. If one number is provided, then that value is used for both X and Y. The values are in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element.

        A negative or zero value disables the effect of the given filter primitive (i.e., the result is the filter input image).

        The <a for=svg>initial value</a> for <a element-attr for=feMorphology>radius</a> is ''0''.

        Animatable: yes.
</dl>

<div class=example>
    <pre><code highlight=svg>
        &lt;svg width="5cm" height="7cm" viewBox="0 0 700 500"
             xmlns="http://www.w3.org/2000/svg"&gt;
          &lt;title&gt;Example feMorphology - Examples of erode and dilate&lt;/title&gt;
          &lt;desc&gt;Five text strings drawn as outlines.
                The first is unfiltered. The second and third use 'erode'.
                The fourth and fifth use 'dilate'.&lt;/desc&gt;
          &lt;defs&gt;
            &lt;filter id="Erode3"&gt;
              &lt;feMorphology operator="erode" in="SourceGraphic" radius="3" /&gt;
            &lt;/filter&gt;
            &lt;filter id="Erode6"&gt;
              &lt;feMorphology operator="erode" in="SourceGraphic" radius="6" /&gt;
            &lt;/filter&gt;
            &lt;filter id="Dilate3"&gt;
              &lt;feMorphology operator="dilate" in="SourceGraphic" radius="3" /&gt;
            &lt;/filter&gt;
            &lt;filter id="Dilate6"&gt;
              &lt;feMorphology operator="dilate" in="SourceGraphic" radius="6" /&gt;
            &lt;/filter&gt;
          &lt;/defs&gt;
          &lt;rect fill="none" stroke="blue" stroke-width="2"
                x="1" y="1" width="698" height="498"/&gt;
          &lt;g isolation="isolate" &gt;
            &lt;g font-family="Verdana" font-size="75"
                      fill="none" stroke="black" stroke-width="6" &gt;
              &lt;text x="50" y="90"&gt;Unfiltered&lt;/text&gt;
              &lt;text x="50" y="180" filter="url(#Erode3)" &gt;Erode radius 3&lt;/text&gt;
              &lt;text x="50" y="270" filter="url(#Erode6)" &gt;Erode radius 6&lt;/text&gt;
              &lt;text x="50" y="360" filter="url(#Dilate3)" &gt;Dilate radius 3&lt;/text&gt;
              &lt;text x="50" y="450" filter="url(#Dilate6)" &gt;Dilate radius 6&lt;/text&gt;
            &lt;/g&gt;
          &lt;/g&gt;
        &lt;/svg&gt;
    </code></pre>

    <div class=figure>
        <img alt="Example of feMorphology" src="examples/feMorphology.png">
        <p class=caption>Example of feMorphology</p>
    </div>

    <a href="examples/feMorphology.svg">View this example as SVG</a>
</div>


## Filter primitive <a element>feOffset</a> ## {#feOffsetElement}

<pre class=include>
path: templates/effect-in1.md
macros:
    name: feOffset
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFEOffsetElement
    attributes: <li><a element-attr for=feOffset>dx</a></li><li><a element-attr for=feOffset>dy</a></li>
</pre>

This filter primitive offsets the input image relative to its current position in the image space by the specified vector.

This is important for effects like drop shadows.

When applying this filter, the destination location may be offset by a fraction of a pixel in device space. <span class="requirement" id="assert_hqFeOffsetInterpolation">In this case a high quality viewer should make use of appropriate interpolation techniques, for example bilinear or bicubic.</span> This is especially recommended for dynamic viewers where this interpolation provides visually smoother movement of images. For static viewers this is less of a concern. Close attention should be made to the 'image-rendering' property setting to determine the authors intent.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feOffset>
    : <dfn>dx</dfn> = "<em><<number>></em>"
    ::
        The amount to offset the input graphic along the x-axis. The offset amount is expressed in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element.

        The <a for=svg>initial value</a> for <a element-attr for=feOffset>dx</a> is ''0''.

        Animatable: yes.
    : <dfn>dy</dfn> = "<em><<number>></em>"
    ::
        The amount to offset the input graphic along the y-axis. The offset amount is expressed in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element.

        The <a for=svg>initial value</a> for <a element-attr for=feOffset>dy</a> is ''0''.

        Animatable: yes.
</dl>

<a href="#intro">The example</a> at the start of this chapter makes use of the <a element>feOffset</a> filter primitive to offset the drop shadow from the original source graphic.


## Filter primitive <a element>feSpecularLighting</a> ## {#feSpecularLightingElement}

<pre class=include>
path: templates/effect-lighting.md
macros:
    name: feSpecularLighting
    interface: SVGFESpecularLightingElement
    attributes: <li><a element-attr for=feSpecularLighting>surfaceScale</a></li><li><a element-attr for=feSpecularLighting>specularConstant</a></li><li><a element-attr for=feSpecularLighting>specularExponent</a></li><li><a element-attr for=feSpecularLighting>kernelUnitLength</a></li>
</pre>

This filter primitive lights a source graphic using the alpha channel as a bump map. The resulting image is an RGBA image based on the light color. The lighting calculation follows the standard specular component of the Blinn-Phong lighting model. The resulting image depends on the light color, light position and surface geometry of the input bump map. The result of the lighting calculation is added. The filter primitive assumes that the viewer is at infinity in the z direction (i.e., the unit vector in the eye direction is (0,0,1) everywhere).

Note: This filter primitive produces an image which contains the specular reflection part of the lighting calculation. Such a map is intended to be combined with a texture from a second filter primitive using the <em>add</em> term of the <em>arithmetic</em> <a element>feComposite</a> method. Multiple <a>light sources</a> can be simulated by adding several of these light maps before applying it to the texture image.

The resulting RGBA image is computed as follows:

<code>
  S<sub>r</sub> = k<sub>s</sub> * pow(N.H, specularExponent) * L<sub>r<br></sub>
  S<sub>g</sub> = k<sub>s</sub> * pow(N.H, specularExponent) * L<sub>g<br></sub>
  S<sub>b</sub> = k<sub>s</sub> * pow(N.H, specularExponent) * L<sub>b<br></sub>
  S<sub>a</sub> = max(S<sub>r,</sub> S<sub>g,</sub> S<sub>b</sub>)
</code>

where

k<sub>s</sub> = specular lighting constant<br>
N = surface normal unit vector, a function of x and y<br>
H = "halfway" unit vector between eye unit vector and light unit vector<br>
<br>
L<sub>r</sub>,L<sub>g</sub>,L<sub>b</sub> = RGB components of light

See <a element>feDiffuseLighting</a> for definition of N and (L<sub>r</sub>, L<sub>g</sub>, L<sub>b</sub>).

The definition of H reflects our assumption of the constant eye vector E = (0,0,1):

<code>
  H = (L + E) / Norm(L+E)
</code>

where L is the light unit vector.

Unlike the <a element>feDiffuseLighting</a>, the <a element>feSpecularLighting</a> filter produces a non-opaque image. This is due to the fact that the specular result (S<sub>r</sub>,S<sub>g</sub>,S<sub>b</sub>,S<sub>a</sub>) is meant to be added to the textured image. The alpha channel of the result is the max of the color components, so that where the specular light is zero, no additional coverage is added to the image and a fully white highlight will add opacity.

The <a element>feDiffuseLighting</a> and <a element>feSpecularLighting</a> filters will often be applied together. An implementation may detect this and calculate both maps in one pass, instead of two.

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feSpecularLighting>
    : <dfn>surfaceScale</dfn> = "<em><<number>></em>"
    ::
        height of surface when A<sub>in</sub> = 1.

        The <a for=svg>initial value</a> for <a element-attr for=feSpecularLighting>surfaceScale</a> is ''1''.

        Animatable: yes.
    : <dfn>specularConstant</dfn> = "<em><<number>></em>"
    ::
        ks in Phong lighting model. In SVG, this can be any non-negative number.

        The <a for=svg>initial value</a> for <a element-attr>specularConstant</a> is ''1''.

        Animatable: yes.
    : <dfn>specularExponent</dfn> = "<em><<number>></em>"
    ::
        Exponent for specular term, larger is more "shiny".

        The <a for=svg>initial value</a> for <a element-attr for=feSpecularLighting>specularExponent</a> is ''1''.

        Animatable: yes.
    : <dfn>kernelUnitLength</dfn> = "<em><<number-optional-number>></em>"
    ::
        The first number is the &lt;dx&gt; value. The second number is the &lt;dy&gt; value.

        If the &lt;dy&gt; value is not specified, it defaults to the same value as &lt;dx&gt;. Indicates the intended distance in current filter units (i.e., units as determined by the value of attribute <a element-attr>primitiveUnits</a>) for <code>dx</code> and <code>dy</code>, respectively, in the <a href="#SurfaceNormalCalculations">surface normal calculation formulas</a>. By specifying value(s) for <a element-attr for=feSpecularLighting>kernelUnitLength</a>, the kernel becomes defined in a scalable, abstract coordinate system.

        If <a element-attr for=feSpecularLighting>kernelUnitLength</a> is not specified, the <code>dx</code> and <code>dy</code> values should represent very small deltas relative to a given <code>(x,y)</code> position, which might be implemented in some cases as one pixel in the intermediate image offscreen bitmap, which is a pixel-based coordinate system, and thus potentially not scalable. For some level of consistency across display media and user agents, it is necessary that a value be provided for <a element-attr for=feSpecularLighting>kernelUnitLength</a>.

        Animatable: yes.
</dl>

The light source is defined by one of the child elements <a element>feDistantLight</a>, <a element>fePointLight</a> or <a element>feSpotLight</a>. The light color is specified by property 'lighting-color'.

<a href="#intro">The example</a> at the start of this chapter makes use of the <a element>feSpecularLighting</a> filter primitive to achieve a highly reflective, 3D glowing effect.

## Filter primitive <a element>feTile</a> ## {#feTileElement}

<pre class=include>
path: templates/effect-in1.md
macros:
    name: feTile
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFETileElement
</pre>

This filter primitive fills a target rectangle with a repeated, tiled pattern of an input image. The target rectangle is as large as the <a>filter primitive subregion</a> established by the <a element>feTile</a> element.

Typically, the input image has been defined with its own <a>filter primitive subregion</a> in order to define a reference tile. <a element>feTile</a> replicates the reference tile in both X and Y to completely fill the target rectangle. The top/left corner of each given tile is at location <code>(x + i*width, y + j*height)</code>, where <code>(x,y)</code> represents the top/left of the input image's <a>filter primitive subregion</a>, <code>width</code> and <code>height</code> represent the width and height of the input image's <a>filter primitive subregion</a>, and <code>i</code> and <code>j</code> can be any integer value. In most cases, the input image will have a smaller <a>filter primitive subregion</a> than the <a element>feTile</a> in order to achieve a repeated pattern effect.

Implementers must take appropriate measures in constructing the tiled image to avoid artifacts between tiles, particularly in situations where the user to device transform includes shear and/or rotation. Unless care is taken, interpolation can lead to edge pixels in the tile having opacity values lower or higher than expected due to the interaction of painting adjacent tiles which each have partial overlap with particular pixels.

## Filter primitive <a element>feTurbulence</a> ## {#feTurbulenceElement}

<pre class=include>
path: templates/effect.md
macros:
    name: feTurbulence
    model: <a element>animate</a>, <a element>script</a>, <a element>set</a>
    interface: SVGFETurbulenceElement
    attributes: <li><a element-attr for=feTurbulence>baseFrequency</a></li><li><a element-attr for=feTurbulence>numOctaves</a></li><li><a element-attr for=feTurbulence>seed</a></li><li><a element-attr for=feTurbulence>stitchTiles</a></li><li><a element-attr for=feTurbulence>type</a></li>
</pre>

This filter primitive creates an image using the Perlin turbulence function. It allows the synthesis of artificial textures like clouds or marble. For a detailed description the of the Perlin turbulence function, see "Texturing and Modeling" [[TaM]]. The resulting image will fill the entire <a>filter primitive subregion</a> for this filter primitive.

It is possible to create bandwidth-limited noise by synthesizing only one octave.

The C code below shows the exact algorithm used for this filter effect. The <a>filter primitive subregion</a> is to be passed as the arguments fTileX, fTileY, fTileWidth and fTileHeight.

For fractalSum, you get a turbFunctionResult that is aimed at a range of -1 to 1 (the actual result might exceed this range in some cases). To convert to a color or alpha value, use the formula <code>colorValue = (turbFunctionResult + 1) / 2</code>, then clamp to the range 0 to 1.

For turbulence, you get a turbFunctionResult that is aimed at a range of 0 to 1 (the actual result might exceed this range in some cases). To convert to a color or alpha value, use the formula <code>colorValue = turbFunctionResult</code>, then clamp to the range 0 to 1.

The following order is used for applying the pseudo random numbers. An initial seed value is computed based on the <a element-attr>seed</a> attribute. Then the implementation computes the lattice points for R, then continues getting additional pseudo random numbers relative to the last generated pseudo random number and computes the lattice points for G, and so on for B and A.

The generated color and alpha values are in the color space determined by the 'color-interpolation-filters' property:

<pre class="svgsamplecompressed"><code highlight=c>
/* Produces results in the range [1, 2**31 - 2].
Algorithm is: r = (a * r) mod m
where a = 16807 and m = 2**31 - 1 = 2147483647
See [Park &amp; Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988
To test: the algorithm should produce the result 1043618065
as the 10,000th generated number if the original seed is 1.
*/
#define RAND_m 2147483647 /* 2**31 - 1 */
#define RAND_a 16807 /* 7**5; primitive root of m */
#define RAND_q 127773 /* m / a */
#define RAND_r 2836 /* m % a */
long setup_seed(long lSeed)
{
  if (lSeed &lt;= 0) lSeed = -(lSeed % (RAND_m - 1)) + 1;
  if (lSeed &gt; RAND_m - 1) lSeed = RAND_m - 1;
  return lSeed;
}
long random(long lSeed)
{
  long result;
  result = RAND_a * (lSeed % RAND_q) - RAND_r * (lSeed / RAND_q);
  if (result &lt;= 0) result += RAND_m;
  return result;
}
#define BSize 0x100
#define BM 0xff
#define PerlinN 0x1000
#define NP 12 /* 2^PerlinN */
#define NM 0xfff
static uLatticeSelector[BSize + BSize + 2];
static double fGradient[4][BSize + BSize + 2][2];
struct StitchInfo
{
  int nWidth; // How much to subtract to wrap for stitching.
  int nHeight;
  int nWrapX; // Minimum value to wrap.
  int nWrapY;
};
static void init(long lSeed)
{
  double s;
  int i, j, k;
  lSeed = setup_seed(lSeed);
  for(k = 0; k &lt; 4; k++)
  {
    for(i = 0; i &lt; BSize; i++)
    {
      uLatticeSelector[i] = i;
      do {
         for (j = 0; j &lt; 2; j++)
           fGradient[k][i][j] = (double)(((lSeed = random(lSeed)) % (BSize + BSize)) - BSize) / BSize;
      } while(fGradient[k][i][0] == 0 && fGradient[k][i][1] == 0);
      s = double(sqrt(fGradient[k][i][0] * fGradient[k][i][0] + fGradient[k][i][1] * fGradient[k][i][1]));
      if (s > 1) {
          i--; // discard the current random vector; try it again.
          continue;
      }
      fGradient[k][i][0] /= s;
      fGradient[k][i][1] /= s;
    }
  }
  while(--i)
  {
    k = uLatticeSelector[i];
    uLatticeSelector[i] = uLatticeSelector[j = (lSeed = random(lSeed)) % BSize];
    uLatticeSelector[j] = k;
  }
  for(i = 0; i &lt; BSize + 2; i++)
  {
    uLatticeSelector[BSize + i] = uLatticeSelector[i];
    for(k = 0; k &lt; 4; k++)
      for(j = 0; j &lt; 2; j++)
        fGradient[k][BSize + i][j] = fGradient[k][i][j];
  }
}
#define s_curve(t) ( t * t * (3. - 2. * t) )
#define lerp(t, a, b) ( a + t * (b - a) )
double noise2(int nColorChannel, double vec[2], StitchInfo *pStitchInfo)
{
  int bx0, bx1, by0, by1, b00, b10, b01, b11;
  double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
  register i, j;
  t = vec[0] + PerlinN;
  bx0 = (int)t;
  bx1 = bx0+1;
  rx0 = t - (int)t;
  rx1 = rx0 - 1.0f;
  t = vec[1] + PerlinN;
  by0 = (int)t;
  by1 = by0+1;
  ry0 = t - (int)t;
  ry1 = ry0 - 1.0f;
  // If stitching, adjust lattice points accordingly.
  if(pStitchInfo != NULL)
  {
    if(bx0 &gt;= pStitchInfo-&gt;nWrapX)
      bx0 -= pStitchInfo-&gt;nWidth;
    if(bx1 &gt;= pStitchInfo-&gt;nWrapX)
      bx1 -= pStitchInfo-&gt;nWidth;
    if(by0 &gt;= pStitchInfo-&gt;nWrapY)
      by0 -= pStitchInfo-&gt;nHeight;
    if(by1 &gt;= pStitchInfo-&gt;nWrapY)
      by1 -= pStitchInfo-&gt;nHeight;
  }
  bx0 &amp;= BM;
  bx1 &amp;= BM;
  by0 &amp;= BM;
  by1 &amp;= BM;
  i = uLatticeSelector[bx0];
  j = uLatticeSelector[bx1];
  b00 = uLatticeSelector[i + by0];
  b10 = uLatticeSelector[j + by0];
  b01 = uLatticeSelector[i + by1];
  b11 = uLatticeSelector[j + by1];
  sx = double(s_curve(rx0));
  sy = double(s_curve(ry0));
  q = fGradient[nColorChannel][b00]; u = rx0 * q[0] + ry0 * q[1];
  q = fGradient[nColorChannel][b10]; v = rx1 * q[0] + ry0 * q[1];
  a = lerp(sx, u, v);
  q = fGradient[nColorChannel][b01]; u = rx0 * q[0] + ry1 * q[1];
  q = fGradient[nColorChannel][b11]; v = rx1 * q[0] + ry1 * q[1];
  b = lerp(sx, u, v);
  return lerp(sy, a, b);
}
double turbulence(int nColorChannel, double *point, double fBaseFreqX, double fBaseFreqY,
          int nNumOctaves, bool bFractalSum, bool bDoStitching,
          double fTileX, double fTileY, double fTileWidth, double fTileHeight)
{
  StitchInfo stitch;
  StitchInfo *pStitchInfo = NULL; // Not stitching when NULL.
  // Adjust the base frequencies if necessary for stitching.
  if(bDoStitching)
  {
    // When stitching tiled turbulence, the frequencies must be adjusted
    // so that the tile borders will be continuous.
    if(fBaseFreqX != 0.0)
    {
      double fLoFreq = double(floor(fTileWidth * fBaseFreqX)) / fTileWidth;
      double fHiFreq = double(ceil(fTileWidth * fBaseFreqX)) / fTileWidth;
      if(fBaseFreqX / fLoFreq &lt; fHiFreq / fBaseFreqX)
        fBaseFreqX = fLoFreq;
      else
        fBaseFreqX = fHiFreq;
    }
    if(fBaseFreqY != 0.0)
    {
      double fLoFreq = double(floor(fTileHeight * fBaseFreqY)) / fTileHeight;
      double fHiFreq = double(ceil(fTileHeight * fBaseFreqY)) / fTileHeight;
      if(fBaseFreqY / fLoFreq &lt; fHiFreq / fBaseFreqY)
        fBaseFreqY = fLoFreq;
      else
        fBaseFreqY = fHiFreq;
    }
    // Set up initial stitch values.
    pStitchInfo = &amp;stitch;
    stitch.nWidth = int(fTileWidth * fBaseFreqX + 0.5f);
    stitch.nWrapX = fTileX * fBaseFreqX + PerlinN + stitch.nWidth;
    stitch.nHeight = int(fTileHeight * fBaseFreqY + 0.5f);
    stitch.nWrapY = fTileY * fBaseFreqY + PerlinN + stitch.nHeight;
  }
  double fSum = 0.0f;
  double vec[2];
  vec[0] = point[0] * fBaseFreqX;
  vec[1] = point[1] * fBaseFreqY;
  double ratio = 1;
  for(int nOctave = 0; nOctave &lt; nNumOctaves; nOctave++)
  {
    if(bFractalSum)
      fSum += double(noise2(nColorChannel, vec, pStitchInfo) / ratio);
    else
      fSum += double(fabs(noise2(nColorChannel, vec, pStitchInfo)) / ratio);
    vec[0] *= 2;
    vec[1] *= 2;
    ratio *= 2;
    if(pStitchInfo != NULL)
    {
      // Update stitch values. Subtracting PerlinN before the multiplication and
      // adding it afterward simplifies to subtracting it once.
      stitch.nWidth *= 2;
      stitch.nWrapX = 2 * stitch.nWrapX - PerlinN;
      stitch.nHeight *= 2;
      stitch.nWrapY = 2 * stitch.nWrapY - PerlinN;
    }
  }
  return fSum;
}
</code></pre>

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feTurbulence>
    : <dfn>baseFrequency</dfn> = "<em><<number-optional-number>></em>"
    ::
        The base frequency (frequencies) parameter(s) for the noise function. If two <<number>>s are provided, the first number represents a base frequency in the X direction and the second value represents a base frequency in the Y direction. If one number is provided, then that value is used for both X and Y.

        The <a for=svg>initial value</a> for <a element-attr>baseFrequency</a> is ''0''.

        Negative values are <a>unsupported</a>.

        Animatable: yes.
    : <dfn>numOctaves</dfn> = "<em><<integer>></em>"
    ::
        The numOctaves parameter for the noise function.

        The <a for=svg>initial value</a> for <a element-attr>numOctaves</a> is ''1''.

        Negative values are <a>unsupported</a>.

        Animatable: yes.

        Note: The contribution of each additional octave to the color and alpha values in the final image is one-half of the preceding octave. At some point, the contribution of additional octaves becomes smaller than the color resolution for a given color depth. UAs may clamp the specified value for numOctaves during the processing depending on the supported color depth. (For example: For a color depth of 8 bits per channel, the UA may clamp the value of numOctaves to 9.)
    : <dfn>seed</dfn> = "<em><<number>></em>"
    ::
        The starting number for the pseudo random number generator.

        The <a for=svg>initial value</a> for <a element-attr>seed</a> is ''0''.

        When the seed number is handed over to the algorithm above it must first be truncated, i.e. rounded to the closest integer value towards zero.

        Animatable: yes.
    : <dfn>stitchTiles</dfn> = "<em>stitch | noStitch</em>"
    ::
        If <code>stitchTiles="noStitch"</code>, no attempt is made to achieve smooth transitions at the border of tiles which contain a turbulence function. Sometimes the result will show clear discontinuities at the tile borders.

        If <code>stitchTiles="stitch"</code>, then the user agent will automatically adjust baseFrequency-x and baseFrequency-y values such that the <a element>feTurbulence</a> node's width and height (i.e., the width and height of the current subregion) contains an integral number of the Perlin tile width and height for the first octave. The baseFrequency will be adjusted up or down depending on which way has the smallest relative (not absolute) change as follows: Given the frequency, calculate <code>lowFreq=floor(width*frequency)/width</code> and <code>hiFreq=ceil(width*frequency)/width</code>. If frequency/lowFreq &lt; hiFreq/frequency then use lowFreq, else use hiFreq. While generating turbulence values, generate lattice vectors as normal for Perlin Noise, except for those lattice points that lie on the right or bottom edges of the active area (the size of the resulting tile). In those cases, copy the lattice vector from the opposite edge of the active area.

        The <a for=svg>initial value</a> for <a element-attr>stitchTiles</a> is ''noStitch''.

        Animatable: yes.
    : <dfn>type</dfn> = "<em>fractalNoise | turbulence</em>"
    ::
        Indicates whether the filter primitive should perform a noise or turbulence function.

        The <a for=svg>initial value</a> for <a element-attr for=feTurbulence>type</a> is ''turbulence''.

        Animatable: yes.
</dl>

<div class=example>
    <pre><code highlight=svg>
        &lt;svg width="450px" height="325px" viewBox="0 0 450 325"
             xmlns="http://www.w3.org/2000/svg"&gt;
          &lt;title&gt;Example feTurbulence - Examples of feTurbulence operations&lt;/title&gt;
          &lt;desc&gt;Six rectangular areas showing the effects of
                various parameter settings for feTurbulence.&lt;/desc&gt;
          &lt;g  font-family="Verdana" text-anchor="middle" font-size="10" &gt;
            &lt;defs&gt;
              &lt;filter id="Turb1" filterUnits="objectBoundingBox"
                      x="0%" y="0%" width="100%" height="100%"&gt;
                &lt;feTurbulence type="turbulence" baseFrequency="0.05" numOctaves="2"/&gt;
              &lt;/filter&gt;
              &lt;filter id="Turb2" filterUnits="objectBoundingBox"
                      x="0%" y="0%" width="100%" height="100%"&gt;
                &lt;feTurbulence type="turbulence" baseFrequency="0.1" numOctaves="2"/&gt;
              &lt;/filter&gt;
              &lt;filter id="Turb3" filterUnits="objectBoundingBox"
                      x="0%" y="0%" width="100%" height="100%"&gt;
                &lt;feTurbulence type="turbulence" baseFrequency="0.05" numOctaves="8"/&gt;
              &lt;/filter&gt;
              &lt;filter id="Turb4" filterUnits="objectBoundingBox"
                      x="0%" y="0%" width="100%" height="100%"&gt;
                &lt;feTurbulence type="fractalNoise" baseFrequency="0.1" numOctaves="4"/&gt;
              &lt;/filter&gt;
              &lt;filter id="Turb5" filterUnits="objectBoundingBox"
                      x="0%" y="0%" width="100%" height="100%"&gt;
                &lt;feTurbulence type="fractalNoise" baseFrequency="0.4" numOctaves="4"/&gt;
              &lt;/filter&gt;
              &lt;filter id="Turb6" filterUnits="objectBoundingBox"
                      x="0%" y="0%" width="100%" height="100%"&gt;
                &lt;feTurbulence type="fractalNoise" baseFrequency="0.1" numOctaves="1"/&gt;
              &lt;/filter&gt;
            &lt;/defs&gt;

            &lt;rect x="1" y="1" width="448" height="323"
                  fill="none" stroke="blue" stroke-width="1"  /&gt;

            &lt;rect x="25" y="25" width="100" height="75" filter="url(#Turb1)"  /&gt;
            &lt;text x="75" y="117"&gt;type=turbulence&lt;/text&gt;
            &lt;text x="75" y="129"&gt;baseFrequency=0.05&lt;/text&gt;
            &lt;text x="75" y="141"&gt;numOctaves=2&lt;/text&gt;

            &lt;rect x="175" y="25" width="100" height="75" filter="url(#Turb2)"  /&gt;
            &lt;text x="225" y="117"&gt;type=turbulence&lt;/text&gt;
            &lt;text x="225" y="129"&gt;baseFrequency=0.1&lt;/text&gt;
            &lt;text x="225" y="141"&gt;numOctaves=2&lt;/text&gt;

            &lt;rect x="325" y="25" width="100" height="75" filter="url(#Turb3)"  /&gt;
            &lt;text x="375" y="117"&gt;type=turbulence&lt;/text&gt;
            &lt;text x="375" y="129"&gt;baseFrequency=0.05&lt;/text&gt;
            &lt;text x="375" y="141"&gt;numOctaves=8&lt;/text&gt;

            &lt;rect x="25" y="180" width="100" height="75" filter="url(#Turb4)"  /&gt;
            &lt;text x="75" y="272"&gt;type=fractalNoise&lt;/text&gt;
            &lt;text x="75" y="284"&gt;baseFrequency=0.1&lt;/text&gt;
            &lt;text x="75" y="296"&gt;numOctaves=4&lt;/text&gt;

            &lt;rect x="175" y="180" width="100" height="75" filter="url(#Turb5)"  /&gt;
            &lt;text x="225" y="272"&gt;type=fractalNoise&lt;/text&gt;
            &lt;text x="225" y="284"&gt;baseFrequency=0.4&lt;/text&gt;
            &lt;text x="225" y="296"&gt;numOctaves=4&lt;/text&gt;

            &lt;rect x="325" y="180" width="100" height="75" filter="url(#Turb6)"  /&gt;
            &lt;text x="375" y="272"&gt;type=fractalNoise&lt;/text&gt;
            &lt;text x="375" y="284"&gt;baseFrequency=0.1&lt;/text&gt;
            &lt;text x="375" y="296"&gt;numOctaves=1&lt;/text&gt;
          &lt;/g&gt;
        &lt;/svg&gt;
    </code></pre>

    <div class=figure>
        <img alt="Example of feTurbulence" src="examples/feTurbulence.png">
        <p class=caption>Example of feTurbulence</p>
    </div>

    <a href="examples/feTurbulence.svg">View this example as SVG</a>
</div>


# The 'color-interpolation-filters' property # {#ColorInterpolationFiltersProperty}

The description of the 'color-interpolation-filters' property is as follows:

<pre class='propdef'>
Name: color-interpolation-filters
Value: auto | sRGB | linearRGB
Initial: linearRGB
Applies to: All <a>filter primitives</a>
Inherited: yes
Percentages: n/a
Computed value: as specified
Media: visual
Animation type: discrete
</pre>

<dl dfn-type=value dfn-for=color-interpolation-filters>
    : <dfn>auto</dfn>
    :: Indicates that the user agent can choose either the ''color-interpolation-filters/sRGB'' or ''color-interpolation-filters/linearRGB'' spaces for filter effects color operations. This option indicates that the author doesn't require that color operations occur in a particular color space.
    : <dfn>sRGB</dfn>
    :: Indicates that filter effects color operations should occur in the gamma-encoded [=sRGB=] color space.
    : <dfn>linearRGB</dfn>
    :: Indicates that filter effects color operations should occur in the [=sRGB-linear|linear-light sRGB=] color space.
</dl>

The 'color-interpolation-filters' property specifies the color space for imaging operations performed via filter effects.

Note: The 'color-interpolation-filters' property just has an affect on filter operations. Therefore, it has no effect on filter primitives like <a element>feOffset</a>, <a element>feImage</a>, <a element>feTile</a> or <a element>feFlood</a>.

Note: The 'color-interpolation-filters' has a different initial value than 'color-interpolation'. 'color-interpolation-filters' has an initial value of  ''linearRGB'', where as 'color-interpolation' has an initial value of ''sRGB''. Thus, in the default case, filter effects operations occur in the linearRGB color space, whereas all other color interpolations occur by default in the sRGB color space.

Note: The 'color-interpolation-filters' property has no affect on <span>Filter Functions, which operate in the sRGB color space.

The 'color-interpolation-filters' property is a <a href="https://www.w3.org/TR/2011/REC-SVG11-20110816/intro.html#TermPresentationAttribute">presentation attribute</a> for SVG elements.

# Light source elements and properties # {#LightSourceDefinitions}

## Introduction ## {#LightSourceIntro}

The following sections define the elements that define a <dfn id="light-source">light source</dfn>, <a element>feDistantLight</a>, <a element>fePointLight</a> and <a element>feSpotLight</a>, and property 'lighting-color', which defines the color of the light.


## Light source <a element>feDistantLight</a> ## {#feDistantLightElement}

<pre class=include>
path: templates/effect-source.md
macros:
    name: feDistantLight
    interface: SVGFEDistantLightElement
    catagories: <a>light source</a>
    attributes: <li><a element-attr for=feDistantLight>azimuth</a></li><li><a element-attr for=feDistantLight>elevation</a></li>
</pre>

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feDistantLight>
    : <dfn>azimuth</dfn> = "<em><<number>></em>"
    ::
        Direction angle for the light source on the XY plane (clockwise), in degrees from the x axis.

        The <a for=svg>initial value</a> for <a element-attr>azimuth</a> is ''0''.

        Animatable: yes.
    : <dfn>elevation</dfn> = "<em><<number>></em>"
    ::
        Direction angle for the light source from the XY plane towards the Z-axis, in degrees. Note that the positive Z-axis points towards the viewer.

        The <a for=svg>initial value</a> for <a element-attr>elevation</a> is ''0''.

        Animatable: yes.
</dl>

The following diagram illustrates the angles which <a element-attr>azimuth</a> and <a element-attr>elevation</a> represent in an XYZ coordinate system.

<div class=figure>
  <img src="examples/azimuth-elevation.svg" alt="Angles which azimuth and elevation represent" width="480" height="360">
  <p class=caption>Angles which azimuth and elevation represent</p>
</div>


## Light source <a element>fePointLight</a> ## {#fePointLightElement}

<pre class=include>
path: templates/effect-source.md
macros:
    name: fePointLight
    interface: SVGFEPointLightElement
    catagories: <a>light source</a>
    attributes: <li><a element-attr for=fePointLight>x</a></li><li><a element-attr for=fePointLight>y</a></li><li><a element-attr for=fePointLight>z</a></li>
</pre>

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=fePointLight>
    : <dfn>x</dfn> = "<em><<number>></em>"
    ::
        X location for the light source in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element.

        The <a for=svg>initial value</a> for <a element-attr for=fePointLight>x</a> is ''0''.

        Animatable: yes.
    : <dfn>y</dfn> = "<em><<number>></em>"
    ::
        Y location for the light source in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element.

        The <a for=svg>initial value</a> for <a element-attr for=fePointLight>y</a> is ''0''.

        Animatable: yes.
    : <dfn>z</dfn> = "<em><<number>></em>"
    ::
        Z location for the light source in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element, assuming that, in the initial <a>local coordinate system</a> , the positive Z-axis comes out towards the person viewing the content and assuming that one unit along the Z-axis equals <a href="https://www.w3.org/TR/SVG11/coords.html#Units_viewport_percentage">one unit in X and Y</a>.

        The <a for=svg>initial value</a> for <a element-attr for=fePointLight>z</a> is ''0''.

        Animatable: yes.
</dl>


## Light source <a element>feSpotLight</a> ## {#feSpotLightElement}

<pre class=include>
path: templates/effect-source.md
macros:
    name: feSpotLight
    interface: SVGFESpotLightElement
    catagories: <a>light source</a>
    attributes: <li><a element-attr for=feSpotLight>x</a></li><li><a element-attr for=feSpotLight>y</a></li><li><a element-attr for=feSpotLight>z</a></li><li><a element-attr for=feSpotLight>pointsAtX</a></li><li><a element-attr for=feSpotLight>pointsAtY</a></li><li><a element-attr for=feSpotLight>pointsAtZ</a></li><li><a element-attr for=feSpotLight>specularExponent</a></li><li><a element-attr for=feSpotLight>limitingConeAngle</a></li>
</pre>

<em>Attribute definitions:</em>
<dl dfn-type=element-attr dfn-for=feSpotLight>
    : <dfn>x</dfn> = "<em><<number>></em>"
    ::
        X location for the light source in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element.

        The <a for=svg>initial value</a> for <a element-attr for=feSpotLight>x</a> is ''0''.

        Animatable: yes.
    : <dfn>y</dfn> = "<em><<number>></em>"
    ::
        Y location for the light source in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element.

        The <a for=svg>initial value</a> for <a element-attr for=feSpotLight>y</a> is ''0''.

        Animatable: yes.
    : <dfn>z</dfn> = "<em><<number>></em>"
    ::
        Z location for the light source in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element, assuming that, in the initial <a>local coordinate system</a>, the positive Z-axis comes out towards the person viewing the content and assuming that one unit along the Z-axis equals <a href="https://www.w3.org/TR/SVG11/coords.html#Units_viewport_percentage">one unit in X and Y</a>.

        The <a for=svg>initial value</a> for <a element-attr for=feSpotLight>z</a> is ''0''.

        Animatable: yes.
    : <dfn>pointsAtX</dfn> = "<em><<number>></em>"
    ::
        X location in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element of the point at which the light source is pointing.

        The <a for=svg>initial value</a> for <a element-attr>pointsAtX</a> is ''0''.

        Animatable: yes.
    : <dfn>pointsAtY</dfn> = "<em><<number>></em>"
    ::
        Y location in the coordinate system established by attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element of the point at which the light source is pointing.

        The <a for=svg>initial value</a> for <a element-attr>pointsAtY</a> is ''0''.

        Animatable: yes.
    : <dfn>pointsAtZ</dfn> = "<em><<number>></em>"
    ::
        Z location in the coordinate system established by the attribute <a element-attr>primitiveUnits</a> on the <a element>filter</a> element of the point at which the light source is pointing, assuming that, in the initial <a>local coordinate system</a>, the positive Z-axis comes out towards the person viewing the content and assuming that one unit along the Z-axis equals <a href="https://www.w3.org/TR/SVG11/coords.html#Units_viewport_percentage">one unit in X and Y</a>.

        The <a for=svg>initial value</a> for <a element-attr>pointsAtZ</a> is ''0''.

        Animatable: yes.
    : <dfn>specularExponent</dfn> = "<em><<number>></em>"
    ::
        Exponent value controlling the focus for the light source.

        The <a for=svg>initial value</a> for <a element-attr for=feSpotLight>specularExponent</a> is ''1''.

        See section <a href="#feDiffuseLightingElement">Filter primitive &lt;feDiffuseLighting></a> for how to use <a element-attr for=feSpotLight>specularExponent</a>.

        Note: <a element-attr for=feSpotLight>specularExponent</a> for <a element>feSpotLight</a> serves a different use case than <a element-attr for=feSpecularLighting>specularExponent</a> for <a element>feSpecularLighting</a>.

        Animatable: yes.
    : <dfn>limitingConeAngle</dfn> = "<em><<number>></em>"
    ::
        A limiting cone which restricts the region where the light is projected. No light is projected outside the cone. <a element-attr>limitingConeAngle</a> represents the angle in degrees between the spot light axis (i.e. the axis between the light source and the point to which it is pointing at) and the spot light cone. <span class="requirement" id="assert_userAgentLightingConeSmoothing">User agents should apply a smoothing technique such as anti-aliasing at the boundary of the cone.</span>

        If no value is specified, then no limiting cone will be applied.

        Animatable: yes.
</dl>


## The 'lighting-color' property ## {#LightingColorProperty}

<pre class='propdef'>
Name: lighting-color
Value: <<color>>
Initial: white
Applies to: <a element>feDiffuseLighting</a> and <a element>feSpecularLighting</a> elements
Inherited: no
Percentages: n/a
Computed value: as specified
Media: visual
Animation type: by computed value
</pre>

The 'lighting-color' property defines the color of the light source for <a>filter primitives</a> <a element>feDiffuseLighting</a> and <a element>feSpecularLighting</a>.

The 'lighting-color' property is a <a href="https://www.w3.org/TR/2011/REC-SVG11-20110816/intro.html#TermPresentationAttribute">presentation attribute</a> for SVG elements.

# Filter CSS <<image>> values # {#FilterCSSImageValue}

CSS <<image>> values can be filtered with the filter functions specified for the CSS 'filter' property. This specification introduces the <<image>> <<filter()>> function with the following syntax:

<pre class=prod><dfn>filter()</dfn> = filter( [ <<image>> | <<string>> ], <<filter-value-list>> )</pre>

The <<filter()>> function takes two arguments. The first argument is an <<image>>. The second is a filter function list as specified for the CSS 'filter' property. The function takes the <<image>> parameter and applies the filter rules, returning a processing image. Filter- and filter effect regions are sized according to the <a>concrete object size</a> of the input <<image>>.

Note: Since the dimension and origin of the original image must be preserved, some filter effects like <<drop-shadow()>> on a fully opaque image may not have any affect.

For the <<blur()>> function the <a element-attr for=feGaussianBlur>edgeMode</a> attribute on the <a element>feGaussianBlur</a> element is set to ''duplicate''. This produces more pleasant results on the edges of the filtered input image.

## Interpolating filter() ## {#interpolating-filter-image}

If both the starting and ending image are <<filter()>>s which may only differ by their used filter functions, they must be interpolated by interpolating their filter function lists as described in section <a href="#interpolation-of-filters">Interpolation of Filters</a>. Otherwise, they must be interpolated as generic <<image>>s. If the filter function interpolation can not be performed, the images must be interpolated as generic <<image>>s.


# Shorthands defined in terms of the <a element>filter</a> element # {#ShorthandEquivalents}

## Filter primitive representation ## {#FilterPrimitiveRepresentation}

Below are the equivalents for each of the filter functions expressed in terms of the 'filter element' element. The parameters from the function are labeled with brackets in the following style: [amount]. In the case of parameters that are percentage values, they are converted to real numbers.


### grayscale ### {#grayscaleEquivalent}

<pre><code highlight=svg>
    &lt;filter id="grayscale"&gt;
      &lt;feColorMatrix type="matrix"
                 values="
        (0.2126 + 0.7874 * [1 - amount]) (0.7152 - 0.7152  * [1 - amount]) (0.0722 - 0.0722 * [1 - amount]) 0 0
        (0.2126 - 0.2126 * [1 - amount]) (0.7152 + 0.2848  * [1 - amount]) (0.0722 - 0.0722 * [1 - amount]) 0 0
        (0.2126 - 0.2126 * [1 - amount]) (0.7152 - 0.7152  * [1 - amount]) (0.0722 + 0.9278 * [1 - amount]) 0 0
        0 0 0 1 0"/&gt;
    &lt;/filter&gt;
</code></pre>



### sepia ### {#sepiaEquivalent}

<pre><code highlight=svg>
    &lt;filter id="sepia"&gt;
      &lt;feColorMatrix type="matrix"
                 values="
        (0.393 + 0.607 * [1 - amount]) (0.769 - 0.769 * [1 - amount]) (0.189 - 0.189 * [1 - amount]) 0 0
        (0.349 - 0.349 * [1 - amount]) (0.686 + 0.314 * [1 - amount]) (0.168 - 0.168 * [1 - amount]) 0 0
        (0.272 - 0.272 * [1 - amount]) (0.534 - 0.534 * [1 - amount]) (0.131 + 0.869 * [1 - amount]) 0 0
        0 0 0 1 0"/&gt;
    &lt;/filter&gt;
</code></pre>


### saturate ### {#saturateEquivalent}

<pre><code highlight=svg>
    &lt;filter id="saturate"&gt;
      &lt;feColorMatrix type="saturate" values="[amount]"/&gt;
    &lt;/filter&gt;
</code></pre>


### hue-rotate ### {#huerotateEquivalent}

<pre><code highlight=svg>
    &lt;filter id="hue-rotate"&gt;
      &lt;feColorMatrix type="hueRotate" values="[angle]"/&gt;
    &lt;/filter&gt;
</code></pre>


### invert ### {#invertEquivalent}

<pre><code highlight=svg>
    &lt;filter id="invert"&gt;
      &lt;feComponentTransfer&gt;
          &lt;feFuncR type="table" tableValues="[amount] (1 - [amount])"/&gt;
          &lt;feFuncG type="table" tableValues="[amount] (1 - [amount])"/&gt;
          &lt;feFuncB type="table" tableValues="[amount] (1 - [amount])"/&gt;
      &lt;/feComponentTransfer&gt;
    &lt;/filter&gt;
</code></pre>


### opacity ### {#opacityEquivalent}

<pre><code highlight=svg>
    &lt;filter id="opacity"&gt;
      &lt;feComponentTransfer&gt;
          &lt;feFuncA type="table" tableValues="0 [amount]"/&gt;
      &lt;/feComponentTransfer&gt;
    &lt;/filter&gt;
</code></pre>


### brightness ### {#brightnessEquivalent}

<pre><code highlight=svg>
    &lt;filter id="brightness"&gt;
      &lt;feComponentTransfer&gt;
          &lt;feFuncR type="linear" slope="[amount]"/&gt;
          &lt;feFuncG type="linear" slope="[amount]"/&gt;
          &lt;feFuncB type="linear" slope="[amount]"/&gt;
      &lt;/feComponentTransfer&gt;
    &lt;/filter&gt;
</code></pre>


### contrast ### {#contrastEquivalent}

<pre><code highlight=svg>
    &lt;filter id="contrast"&gt;
      &lt;feComponentTransfer&gt;
          &lt;feFuncR type="linear" slope="[amount]" intercept="-(0.5 * [amount]) + 0.5"/&gt;
          &lt;feFuncG type="linear" slope="[amount]" intercept="-(0.5 * [amount]) + 0.5"/&gt;
          &lt;feFuncB type="linear" slope="[amount]" intercept="-(0.5 * [amount]) + 0.5"/&gt;
      &lt;/feComponentTransfer&gt;
    &lt;/filter&gt;
</code></pre>


### blur ### {#blurEquivalent}

<pre><code highlight=svg>
    &lt;filter id="blur"&gt;
      &lt;feGaussianBlur stdDeviation="[radius radius]" edgeMode="[edge mode]" &gt;
    &lt;/filter&gt;
</code></pre>

Where edge mode computes to ''filter/none'' for the 'filter' property and to ''duplicate'' for the CSS Image <<filter()>> function.

Note: The <<blur()>> function may increase the UA defined filter region. See <a href="#filter-region-for-shorthands">Filter region for shorthands</a>.

### drop-shadow ### {#dropshadowEquivalent}

<pre><code highlight=svg>
    &lt;filter id="drop-shadow"&gt;
      &lt;feGaussianBlur in="[alpha-channel-of-input]" stdDeviation="[radius]"/&gt;
      &lt;feOffset dx="[offset-x]" dy="[offset-y]" result="offsetblur"/&gt;
      &lt;feFlood flood-color="[color]"/&gt;
      &lt;feComposite in2="offsetblur" operator="in"/&gt;
      &lt;feMerge&gt;
        &lt;feMergeNode/&gt;
        &lt;feMergeNode in="[input-image]"/&gt;
      &lt;/feMerge&gt;
    &lt;/filter&gt;
</code></pre>

Note: The <<drop-shadow()>> function may increase the UA defined filter region. See <a href="#filter-region-for-shorthands">Filter region for shorthands</a>.

## Filter region for shorthands ## {#filter-region-for-shorthands}

All shorthand filters implemented with filter primitives in the previous subsection must have a UA defined <a>filter region</a>. The filter region must cover the visual content of an element including overflowing content, graphical control elements such as scrollbars, 'border'/'border-image', 'box-shadow', 'text-shadow' and 'outline'. Furthermore, if a shorthand filter expands this visible area like it is the case for <<blur()>> or <<drop-shadow()>> the filter region must cover this area as well.

Note: For the handling of <a href="#FilterElement">filter sources</a> see section <a href="#FilterEffectsRegion">Filter region</a>.


# Animation of Filters # {#animation-of-filters}

## Interpolation of Filter Function Lists## {#interpolation-of-filters}

For interpolation between one filter and a second, the steps corresponding to the first matching condition in the following list must be run:

<dl class=switch>
  <dt id='from-to-animation-equal'>If both filters have a <<filter-value-list>> of same length without <<filter/url>> and for each <<filter-function>> for which there is a corresponding item in each list
  <dd>Interpolate each <<filter-function>> pair following the rules in section <a href='#interpolation-of-filter-functions'>Interpolation of Filter Functions</a>.</dd>
  <dt id='from-to-animation-unequal'>If both filters have a <<filter-value-list>> of different length without <<filter/url>> and for each <<filter-function>> for which there is a corresponding item in each list
  <dd>
    <ol class=algorithm>
      <li>Append the missing equivalent <<filter-function>>s from the longer list to the end of the shorter list. The new added <<filter-function>>s must be initialized to their initial values for interpolation.</li>
      <li>Interpolate each <<filter-function>> pair following the rules in section <a href='#interpolation-of-filter-functions'>Interpolation of Filter Functions</a>.</li>
    </ol>
  </dd>
  <dt id='interpolation-none-filter-functions'>If one filter is ''filter/none'' and the other is a <<filter-value-list>> without <<filter/url>></dt>
  <dd>
    <ol class=algorithm>
      <li>Replace ''filter/none'' with the corresponding <<filter-value-list>> of the other filter. The new <<filter-function>>s must be initialized to their initial values for interpolation.</li>
      <li>Interpolate each <<filter-function>> pair following the rules in section <a href='#interpolation-of-filter-functions'>Interpolation of Filter Functions</a>.</li>
    </ol>
  </dd>
  <dt id='no-interpolation'>Otherwise</dt>
  <dd>Use discrete interpolation.</dd>
</dl>

Issue(91): Compute distance of filter functions.

## Addition ## {#addition}

It is possible to combine independent animations of <<filter-value-list>>s [[SVG11]].

Given two filter values representing an base value (<var>base filter list</var>) and a value to add (<var>added filter list</var>), returns the concatenation of the the two lists: &lsquo;<var>base filter list</var> <var>added filter list</var>&rsquo;.

<div class=example>
    The following SVG animation has two <a element>animate</a> elements animating 'filter' property of the <a element>rect</a> element. Both specified animations are additive and have a duration of <var>10s</var>.

    <pre><code highlight=svg>
        &lt;rect width="200px" filter="none" ...>
          &lt;animate attributeName="filter" from="blur(0px)" to="blur(10px)" dur="10s"
                   additive="sum"/>
          &lt;animate attributeName="filter" from="sepia(0)" to="sepia(1)" dur="10s"
                   additive="sum"/>
        &lt;/rect>
    </code></pre>

    After <var>5s</var>, the <a>used value</a> of 'filter' is ''blur(5px) sepia(0.5)''.
</div>


## Accumulation ## {#accumulation}

Accumulation of <<filter-value-list>>s follows the same matching and extending
rules as <a href='#interpolation-of-filters'>interpolation</a>, falling back to
[=composite operation replace|replace=] behavior if the lists do not match.
However instead of interpolating the matching <<filter-function>> pairs, their
arguments are arithmetically added together - except in the case of
<<filter-function>>s whose initial value for interpolation is 1, which combine
using one-based addition:

  <var ignore>V<sub>result</sub></var> =
  <var>V<sub>a</sub></var> + <var ignore>V<sub>b</sub></var> - 1

<h2 id="priv-sec">Privacy and Security Considerations</h2>

<h3 id="tainted-filter-primitives">Tainted Filter Primitives</h3>

It is important that the timing of any filter operation is independent of pixel values derived from the filtered content or other sources potentially containing privacy-sensitive information.

The following <a>filter primitives</a> may have access to pixel values that potentially contain privacy-sensitive information, either from the filtered object itself or other sources such as CSS styling. These primitives must be flagged as "tainted".

1. <a element>feFlood</a> when the <a>specified value</a> of the 'flood-color' property computes to ''currentColor'',
2. <a element>feDropShadow</a> when the <a>specified value</a> value of the 'flood-color' property computes to ''currentColor'',
3. <a element>feDiffuseLighting</a>, when the <a>specified value</a> value of the 'lighting-color' property computes to ''currentColor''
4. <a element>feSpecularLighting</a> when the <a>specified value</a> value of the 'lighting-color' property computes to ''currentColor'',
5. <a element>feImage</a>, when the <<filter/url>> reference points to an element or fetches a resource with the fetching mode <em>No-CORS</em> and
6. the filter primitives: <a attr-value>SourceGraphic</a>, <a attr-value>SourceAlpha</a>, <a attr-value>BackgroundImage</a>, <a attr-value>BackgroundAlpha</a>, <a attr-value>FillPaint</a> and <a attr-value>StrokePaint</a>.

<a element>feFlood</a>, <a element>feDropShadow</a>, <a element>feDiffuseLighting</a> and <a element>feSpecularLighting</a> are primitives with one or more CSS properties that take <<color>> as property value. <<color>> consists of (amongst others) the ''currentColor'' keyword. The <a>used value</a> for ''currentColor'' derives from the 'color' property. Since 'color' can be set by the '':visited'' pseudo selector, it potentially contains privacy-sensitive information and therefore these primitives must be marked as tainted.

<a element>feImage</a> can reference cross-domain images as well as document fragments such as SVG <a>graphics elements</a>. These references potentially contain privacy-sensitive information and therefore the primitive must be marked as tainted.

The filter primitives <a attr-value>SourceGraphic</a>, <a attr-value>SourceAlpha</a>, <a attr-value>BackgroundImage</a>, <a attr-value>BackgroundAlpha</a>, <a attr-value>FillPaint</a> and <a attr-value>StrokePaint</a> either reference document fragments such as SVG <a>graphics elements</a> or style information that may derive directly or indirectly from the 'color' property. Therefore these primitives must be marked as tainted.

Every <a>filter primitive</a> that has a "tainted" flagged <a>filter primitive</a> as input must be flagged as "tainted" as well.

Filter operations must be implemented in such a way that they always take the same amount of time regardless of the pixel values if one of the input filter primitives is flagged as "tainted".

Note: This specification aggravates the restrictions to filter primitives based on implementation feedback from user agents.

<h3 id="fedisplacemnentmap-restrictions"><a element>feDisplacementMap</a> Restrictions</h3>

If <a element>feDisplacementMap</a> has a "tainted" flagged filter primitive as input and this input filter primitive is used as displacement map (referenced by <a element-attr for=feDisplacementMap>in2</a>), then <a element>feDisplacementMap</a> must not proceed with the filter operation and acts as a <a>pass through filter</a>.

<h3 id="origin-restrictions">Origin Restrictions</h3>

User agents must use the <a>CORS request</a> defined by the [[!Fetch]] specification for the 'filter' property. When fetching, user agents must use "Anonymous" mode, set the referrer source to the stylesheet's URL and set the origin to the URL of the containing document. If this results in network errors, the effect is as if the value ''filter/none'' had been specified.

<h3 id="timing-attack">Timing Attacks</h3>

If any of the above rules are not followed, an attacker could infer information and mount a timing attack.

A timing attack is a method of obtaining information about content that is otherwise protected, based on studying the amount of time it takes for an operation to occur. If, for example, red pixels took longer to draw than green pixels, one might be able to reconstruct a rough image of the element being rendered, without ever having access to the content of the element. Security studies show that timing differences on arithmetic operations can be caused by the hardware architecture or compiler [[ArTD]].


<h2 id="AccessBackgroundImage" class="no-num">Appendix A: The deprecated <css>enable-background</css> property</h2>

SVG 1.1 introduced the <a href="https://www.w3.org/TR/SVG11/filters.html#EnableBackgroundProperty">enable-background</a> property [[SVG11]]. The property defined the back drop under the <a>filter region</a> at the time that the <a element>filter</a> element was invoked. The concept defined by this property was identified to be incompatible with the model of stacking context in CSS at the time writing this specification. UAs can choose to implement the <a href="https://www.w3.org/TR/SVG11/filters.html#EnableBackgroundProperty">enable-background</a> property as defined in SVG 1.1 but will not be compatible to this specification or to CSS Compositing and Blending [[!COMPOSITING-1]].

This specification does not support the <a href="https://www.w3.org/TR/SVG11/filters.html#EnableBackgroundProperty">enable-background</a> property. UAs must support the 'isolation' property instead [[!COMPOSITING-1]].


<h2 id="DOMInterfaces" class="no-num">Appendix B: DOM interfaces</h2>

<!-- external: WebIDL interfaces -->
<pre class=include>
path: appendix/interfaces.md
</pre>

<h2 class="no-num" id="changes">Changes</h2>

The following significant changes were made since the <a href="https://www.w3.org/TR/2014/WD-filter-effects-1-20141125/">25 November 2014 Working Draft</a>.

* Editorial changes.
* Add description elements to content model of all elements.
* Clarify that crossorigin is not animatable.
* <<hue-rotate()>> takes unitless zero.
* Allow author to change order of <<color>> and <<length>> values of <<drop-shadow()>>. Change grammar to put <<color>> first. Differentiate between initial value for interpolation and default values for omitted values.
* Define animation type of CSS properties.
* Make <a element>feColorMatrix</a> and <a element>feConvolveMatrix</a> a pass through on unfulfilled pre-conditions.
* Make <a element>feTurbulence</a> algorithms respect uniformity.
* Apply properties that apply to all graphics elements to the use element as well.
* Corrected filter primitive representation of <<saturate()>>.
* Extend SVG DOM SVGFEBlendElement enumerations with new blend modes.

The following significant changes were made since the <a href="https://www.w3.org/TR/2013/WD-filter-effects-1-20131126/">26 November 2013 Working Draft</a>.

* Removed Custom Filters.
* Allow the <a element>script</a> element in the content model everywhere.
* Support all blend modes from CSS Blending specification for <a element>feBlend</a>.
* Support all non-duplicated compositing modes from CSS Blending specification for <a element>feComposite</a>.
* Added no-composite attribute to <a element>feBlend</a> to avoid double compositing.
* Corrections on shorthands syntax.
* Added definition for shorthand filter regions.

The following significant changes were made since the <a href="https://www.w3.org/TR/2012/WD-filter-effects-20121025/">25 October 2012 Working Draft</a>.

* Correction of brightness short hand filter.
* New syntax for Custom Filter function.
* Add at-function rule for Custom Filters.
* Allow Custom Filter function to be used as extension for future filter features.
* Remove unnecessary attributes and uniforms on shaders.
* Redefine origin of shader coordinate space to bottom left.
* Remove now unnecessary filter-margin properties.

See more detailed and longterm changes in the <a href="ChangeLog">ChangeLog</a>.


<h2 class=no-num id='acknowledgments'>Acknowledgments</h2>

The editors would like to thank Robert O’Callahan, Coralie Mercier, Chris Lilley, Nikos Andronikos, Stephen Chenney, Simon Fraser, Tavmjong Bah, Robert Longson, Cameron McCormack, Brad Kemper, Tab Atkins, Brian Birtles, Michael Mullany, Rik Cabanier, Anne van Kesteren, Boris Zbarsky, Kristopher Giesing, Stephen White, Jasper van de Gronde, Kang-Hao Lu, Paul LeBeau, Debarshi Ray, Jarek Foksa, Sebastian Zartner, Yuqian Li, Amelia Bellamy-Royds and Max Vujovic for their careful reviews, comments, and corrections.
